perm filename CLOOPS.4[COM,LSP] blob
sn#857154 filedate 1988-05-15 generic text, type C, neo UTF8
COMMENT ⊗ VALID 00660 PAGES
C REC PAGE DESCRIPTION
C00001 00001
C00099 00002
C00100 00003 ∂05-Oct-87 1028 Kahn.pa@Xerox.COM Re: no-applicable-method
C00105 00004 ∂09-Oct-87 1428 Gregor.pa@Xerox.COM [goldman@vaxa.isi.edu: miscellaneous CLOS topics]
C00112 00005 ∂09-Oct-87 1539 RPG Shared/classlocal/instance
C00115 00006 ∂09-Oct-87 1618 Gregor.pa@Xerox.COM Shared/classlocal/instance
C00117 00007 ∂09-Oct-87 1610 Gregor.pa@Xerox.COM meeting at x3j13
C00118 00008 ∂09-Oct-87 1818 Moon@STONY-BROOK.SCRC.Symbolics.COM meeting at x3j13
C00120 00009 ∂09-Oct-87 1820 Moon@STONY-BROOK.SCRC.Symbolics.COM Shared/classlocal/instance
C00122 00010 ∂10-Oct-87 1404 RPG Writing
C00123 00011 ∂11-Oct-87 2101 RPG Extent of CALL-NEXT-METHOD
C00124 00012 ∂12-Oct-87 0724 @RELAY.CS.NET:DUSSUD@jenner.csc.ti.com Re: Shared/classlocal/instance
C00126 00013 ∂12-Oct-87 0724 @RELAY.CS.NET:DUSSUD@jenner.csc.ti.com Re: meeting at x3j13
C00128 00014 ∂12-Oct-87 0724 @RELAY.CS.NET:DUSSUD@jenner.csc.ti.com Re: Extent of CALL-NEXT-METHOD
C00130 00015 ∂12-Oct-87 0851 Gregor.pa@Xerox.COM Extent of CALL-NEXT-METHOD
C00131 00016 ∂12-Oct-87 0913 Bobrow.pa@Xerox.COM Re: Extent of CALL-NEXT-METHOD
C00132 00017 ∂12-Oct-87 0918 Bobrow.pa@Xerox.COM Re: Extent of CALL-NEXT-METHOD
C00133 00018 ∂12-Oct-87 1102 Moon@STONY-BROOK.SCRC.Symbolics.COM Extent of CALL-NEXT-METHOD
C00136 00019 ∂12-Oct-87 1130 @Score.Stanford.EDU:kempf%hplabsz@hplabs.HP.COM Re: meeting at x3j13
C00138 00020 ∂12-Oct-87 1131 @Score.Stanford.EDU:kempf%hplabsz@hplabs.HP.COM Re: Shared/classlocal/instance
C00140 00021 ∂12-Oct-87 1131 @Score.Stanford.EDU:kempf%hplabsz@hplabs.HP.COM Re: Extent of CALL-NEXT-METHOD
C00142 00022 ∂12-Oct-87 1145 MASINTER.PA@Xerox.COM extent of CALL-NEXT-METHOD
C00143 00023 ∂12-Oct-87 1348 Gregor.pa@Xerox.COM Extent of CALL-NEXT-METHOD
C00146 00024 ∂12-Oct-87 1351 Moon@STONY-BROOK.SCRC.Symbolics.COM fixing our problems with setf
C00159 00025 ∂12-Oct-87 1357 Moon@STONY-BROOK.SCRC.Symbolics.COM Extent of CALL-NEXT-METHOD
C00161 00026 ∂12-Oct-87 1553 @RELAY.CS.NET:DUSSUD@jenner.csc.ti.com Re: Constructors
C00166 00027 ∂12-Oct-87 1615 @RELAY.CS.NET:DUSSUD@jenner.csc.ti.com
C00170 00028 ∂12-Oct-87 1727 @RELAY.CS.NET:DUSSUD@jenner.csc.ti.com Re: fixing our problems with setf
C00175 00029 ∂12-Oct-87 1729 @RELAY.CS.NET:DUSSUD@jenner.csc.ti.com Re: Shared/classlocal/instance
C00178 00030 ∂12-Oct-87 1737 RPG shared/classlocal/instance
C00179 00031 ∂12-Oct-87 1743 Bobrow.pa@Xerox.COM Re: Shared/classlocal/instance
C00181 00032 ∂12-Oct-87 1803 Moon@STONY-BROOK.SCRC.Symbolics.COM Object Creation Writeup
C00223 00033 ∂12-Oct-87 1814 Moon@STONY-BROOK.SCRC.Symbolics.COM Object Creation Writeup
C00225 00034 ∂13-Oct-87 0910 @Score.Stanford.EDU:kempf%hplabsz@hplabs.HP.COM Name Change for Metaobject Protocol?
C00230 00035 ∂13-Oct-87 0930 Bobrow.pa@Xerox.COM Re: Name Change for Metaobject Protocol?
C00234 00036 ∂13-Oct-87 1021 Gregor.pa@Xerox.COM Name Change for Metaobject Protocol?
C00236 00037 ∂13-Oct-87 1052 Gregor.pa@Xerox.COM fixing our problems with setf
C00241 00038 ∂13-Oct-87 1103 Gregor.pa@Xerox.COM Extent of CALL-NEXT-METHOD
C00244 00039 ∂13-Oct-87 1103 Gregor.pa@Xerox.COM reinitializing class slots
C00246 00040 ∂13-Oct-87 1114 Moon@STONY-BROOK.SCRC.Symbolics.COM fixing our problems with setf
C00248 00041 ∂13-Oct-87 1348 Moon@STONY-BROOK.SCRC.Symbolics.COM fixing our problems with setf
C00262 00042 ∂13-Oct-87 1427 RPG Status
C00264 00043 ∂13-Oct-87 1436 Moon@STONY-BROOK.SCRC.Symbolics.COM fixing our problems with setf
C00277 00044 ∂13-Oct-87 1459 Gregor.pa@Xerox.COM fixing our problems with setf
C00294 00045 ∂13-Oct-87 1817 Bobrow.pa@Xerox.COM Re: fixing our problems with setf
C00298 00046 ∂13-Oct-87 1845 Pavel.pa@Xerox.COM Re: fixing our problems with setf
C00301 00047 ∂13-Oct-87 1900 Moon@STONY-BROOK.SCRC.Symbolics.COM Re: fixing our problems with setf
C00304 00048 ∂13-Oct-87 1904 Moon@STONY-BROOK.SCRC.Symbolics.COM Re: fixing our problems with setf
C00310 00049 ∂13-Oct-87 2009 Pavel.pa@Xerox.COM Re: fixing our problems with setf
C00312 00050 ∂14-Oct-87 0827 @STONY-BROOK.SCRC.Symbolics.COM,@JUNCO.SCRC.Symbolics.COM:skeene@STONY-BROOK.SCRC.Symbolics.COM status of "object" or "standard-object"
C00315 00051 ∂14-Oct-87 0950 @Score.Stanford.EDU:kempf%hplabsz@hplabs.HP.COM Re: status of "object" or "standard-object"
C00318 00052 ∂14-Oct-87 0950 @Score.Stanford.EDU:kempf%hplabsz@hplabs.HP.COM Re: Name Change for Metaobject Protocol?
C00320 00053 ∂14-Oct-87 1026 @Score.Stanford.EDU:kempf%hplabsz@hplabs.HP.COM Re: Status (and TRACE-EXECUTION spec)
C00325 00054 ∂14-Oct-87 1029 @Score.Stanford.EDU:kempf%hplabsz@hplabs.HP.COM Re: Constructors
C00328 00055 ∂14-Oct-87 1046 Moon@STONY-BROOK.SCRC.Symbolics.COM Re: fixing our problems with setf
C00331 00056 ∂14-Oct-87 1620 DLW@ALDERAAN.SCRC.Symbolics.COM Name Change for Metaobject Protocol?
C00333 00057 ∂16-Oct-87 0639 Moon@MEAD.SCRC.Symbolics.COM CLASS-CHANGED and UPDATE-OBSOLETE-INSTANCE
C00335 00058 ∂16-Oct-87 0659 Moon@MEAD.SCRC.Symbolics.COM CLASS-CHANGED and UPDATE-OBSOLETE-INSTANCE
C00337 00059 ∂17-Oct-87 1157 RPG Constructors
C00338 00060 ∂18-Oct-87 2151 RPG The Results are In!
C00339 00061 ∂19-Oct-87 0806 @Score.Stanford.EDU:kempf%hplabsz@hplabs.HP.COM Re: The Results are In!
C00341 00062 ∂19-Oct-87 0900 Bobrow.pa@Xerox.COM initialize-instance on an exisiting instance
C00343 00063 ∂19-Oct-87 0932 Moon@YUKON.SCRC.Symbolics.COM initialize-instance on an exisiting instance
C00347 00064 ∂19-Oct-87 0951 Bobrow.pa@Xerox.COM Re: The Results are In!
C00349 00065 ∂19-Oct-87 1016 Bobrow.pa@Xerox.COM Re: initialize-instance on an exisiting instance
C00355 00066 ∂19-Oct-87 1826 Bobrow.pa@Xerox.COM Re: Constructors
C00356 00067 ∂20-Oct-87 0926 RPG Constructors
C00357 00068 ∂20-Oct-87 1028 Bobrow.pa@Xerox.COM Re: Constructors
C00360 00069 ∂20-Oct-87 1033 skeene@STONY-BROOK.SCRC.Symbolics.COM Constructors
C00362 00070 ∂20-Oct-87 1923 Pavel.pa@Xerox.COM The extent of CALL-NEXT-METHOD (a retraction)
C00366 00071 ∂21-Oct-87 0835 @Score.Stanford.EDU:kempf%hplabsz@hplabs.HP.COM Re: The extent of CALL-NEXT-METHOD (a retraction)
C00372 00072 ∂21-Oct-87 0848 @Score.Stanford.EDU:kempf%hplabsz@hplabs.HP.COM Re: Constructors
C00377 00073 ∂21-Oct-87 0956 Moon@STONY-BROOK.SCRC.Symbolics.COM indefinite extent of call-next-method
C00379 00074 ∂21-Oct-87 1000 @Score.Stanford.EDU:kempf%hplabsz@hplabs.HP.COM TRACE Proposal
C00389 00075 ∂21-Oct-87 1032 RPG The Latest Draft
C00390 00076 ∂21-Oct-87 1114 Gregor.pa@Xerox.COM indefinite extent of call-next-method
C00393 00077 ∂21-Oct-87 1254 @RELAY.CS.NET:DUSSUD@jenner.csc.ti.com Re: Constructors
C00399 00078 ∂21-Oct-87 1649 Bobrow.pa@Xerox.COM Re: Constructors
C00403 00079 ∂21-Oct-87 2033 @STONY-BROOK.SCRC.Symbolics.COM,@EUPHRATES.SCRC.Symbolics.COM:Moon@STONY-BROOK.SCRC.Symbolics.COM First round of comments on the draft document
C00417 00080 ∂22-Oct-87 0837 skeene@STONY-BROOK.SCRC.Symbolics.COM My comments on Chapter 1
C00427 00081 ∂22-Oct-87 0842 @Score.Stanford.EDU:kempf%hplabsz@hplabs.HP.COM Re: indefinite extent of call-next-method
C00434 00082 ∂22-Oct-87 1037 Moon@STONY-BROOK.SCRC.Symbolics.COM Rest of comments on chapter 1 of the draft document
C00440 00083 ∂22-Oct-87 1103 @RELAY.CS.NET:DUSSUD@jenner.csc.ti.com Re: Constructors
C00447 00084 ∂22-Oct-87 1054 Moon@STONY-BROOK.SCRC.Symbolics.COM Re: indefinite extent of call-next-method
C00460 00085 ∂22-Oct-87 1108 Moon@STONY-BROOK.SCRC.Symbolics.COM Keene comments on Chapter 1
C00464 00086 ∂22-Oct-87 1129 Masinter.pa@Xerox.COM Re: indefinite extent of call-next-method
C00466 00087 ∂22-Oct-87 1227 RPG Extent
C00471 00088 ∂22-Oct-87 1303 Moon@STONY-BROOK.SCRC.Symbolics.COM Comments on chapter 2, through defgeneric
C00483 00089 ∂22-Oct-87 1306 @Score.Stanford.EDU:kempf%hplabsz@hplabs.HP.COM Re: indefinite extent of call-next-method
C00486 00090 ∂22-Oct-87 1318 Bobrow.pa@Xerox.COM Re: Extent
C00489 00091 ∂22-Oct-87 1338 RPG Clear Versus Black Box
C00490 00092 ∂22-Oct-87 1424 Pavel.pa@Xerox.COM Comments on comments on Chapter 1
C00498 00093 ∂22-Oct-87 1446 Moon@STONY-BROOK.SCRC.Symbolics.COM Comments on comments on Chapter 1
C00503 00094 ∂22-Oct-87 1458 Pavel.pa@Xerox.COM Re: Comments on comments on Chapter 1
C00506 00095 ∂22-Oct-87 1521 Bobrow.pa@Xerox.COM Re: Clear Versus Black Box
C00508 00096 ∂22-Oct-87 1536 Bobrow.pa@Xerox.COM Re: Clear Versus Black Box
C00510 00097 ∂22-Oct-87 1544 Moon@STONY-BROOK.SCRC.Symbolics.COM Second set of comments on chapter 2
C00522 00098 ∂22-Oct-87 1554 RPG 0-ary generic functions
C00523 00099 ∂22-Oct-87 1606 @STONY-BROOK.SCRC.Symbolics.COM,@EUPHRATES.SCRC.Symbolics.COM:Moon@STONY-BROOK.SCRC.Symbolics.COM 0-ary generic functions
C00526 00100 ∂22-Oct-87 1622 Bobrow.pa@Xerox.COM Re: Comments on comments on Chapter 1
C00529 00101 ∂22-Oct-87 1622 Bobrow.pa@Xerox.COM Re: Comments on comments on Chapter 1
C00531 00102 ∂22-Oct-87 1622 Bobrow.pa@Xerox.COM Re: First round of comments on the draft document
C00535 00103 ∂22-Oct-87 1631 Bobrow.pa@Xerox.COM Re: 0-ary generic functions
C00538 00104 ∂22-Oct-87 1840 Moon@YUKON.SCRC.Symbolics.COM comments on some standard type classes
C00549 00105 ∂22-Oct-87 1907 Moon@YUKON.SCRC.Symbolics.COM standard-type-class or built-in-class
C00556 00106 ∂22-Oct-87 1947 Pavel.pa@Xerox.COM My comments on Chapter 1
C00570 00107 ∂22-Oct-87 2004 @STONY-BROOK.SCRC.Symbolics.COM,@EUPHRATES.SCRC.Symbolics.COM:Moon@STONY-BROOK.SCRC.Symbolics.COM Comments on final portion of Chapter 2
C00578 00108 ∂22-Oct-87 2252 RPG Pavel's Comments
C00582 00109 ∂23-Oct-87 0845 @Score.Stanford.EDU:kempf%hplabsz@hplabs.HP.COM Re: Constructors
C00588 00110 ∂23-Oct-87 1041 @STONY-BROOK.SCRC.Symbolics.COM,@EUPHRATES.SCRC.Symbolics.COM:Moon@STONY-BROOK.SCRC.Symbolics.COM Comments on (the skeleton of) Chapter 3
C00598 00111 ∂23-Oct-87 1055 Moon@STONY-BROOK.SCRC.Symbolics.COM Extent
C00600 00112 ∂23-Oct-87 1123 Moon@STONY-BROOK.SCRC.Symbolics.COM Re: Comments on comments on Chapter 1
C00604 00113 ∂23-Oct-87 1127 Pavel.pa@Xerox.COM Class naming
C00607 00114 ∂23-Oct-87 1133 Pavel.pa@Xerox.COM Re: Pavel's Comments
C00611 00115 ∂23-Oct-87 1206 Moon@STONY-BROOK.SCRC.Symbolics.COM Re: Pavel's Comments
C00614 00116 ∂23-Oct-87 1240 RPG Pavel
C00615 00117 ∂23-Oct-87 1247 RPG Undefined Definition
C00617 00118 ∂23-Oct-87 1250 RPG Adjustable Arrays and Error Terminology
C00618 00119 ∂23-Oct-87 1333 Bobrow.pa@Xerox.COM Comments on Chapter 1
C00629 00120 ∂23-Oct-87 1445 Pavel.pa@Xerox.COM Re: Undefined Definition
C00632 00121 ∂23-Oct-87 1457 Moon@STONY-BROOK.SCRC.Symbolics.COM More comments on the draft document
C00637 00122 ∂23-Oct-87 1550 Bobrow.pa@Xerox.COM More on Class names
C00639 00123 ∂23-Oct-87 1633 Moon@STONY-BROOK.SCRC.Symbolics.COM More on Class names
C00641 00124 ∂23-Oct-87 1716 Masinter.pa@Xerox.COM Environment-arguments, MACRO-FUNCTION-ENVIRONMENT
C00644 00125 ∂23-Oct-87 1851 Gregor.pa@Xerox.COM status of "object" or "standard-object"
C00648 00126 ∂26-Oct-87 1032 @RELAY.CS.NET:DUSSUD@jenner.csc.ti.com "Object" Class.
C00651 00127 ∂26-Oct-87 2146 COMMON-LISP-OBJECT-SYSTEM-mailer Some open issues
C00673 00128 ∂26-Oct-87 2202 Common-Lisp-Object-System-mailer Proof of CLOS Document
C00686 00129 ∂27-Oct-87 0845 Common-Lisp-Object-System-mailer Proof of CLOS Document
C00696 00130 ∂27-Oct-87 0852 Common-Lisp-Object-System-mailer status of "object" or "standard-object"
C00698 00131 ∂27-Oct-87 1051 Common-Lisp-Object-System-mailer Some open issues
C00701 00132 ∂28-Oct-87 0856 Common-Lisp-Object-System-mailer Re: Proof of CLOS Document
C00709 00133 ∂29-Oct-87 0918 Common-Lisp-Object-System-mailer Re: Some open issues
C00714 00134 ∂29-Oct-87 1109 Common-Lisp-Object-System-mailer comments on revised Chapter 1
C00719 00135 ∂29-Oct-87 1259 Common-Lisp-Object-System-mailer Re: Some open issues
C00723 00136 ∂29-Oct-87 2147 Common-Lisp-Object-System-mailer standard type class
C00738 00137 ∂30-Oct-87 0809 Common-Lisp-Object-System-mailer Re: standard type class
C00741 00138 ∂30-Oct-87 0858 Common-Lisp-Object-System-mailer Re: Some open issues
C00746 00139 ∂30-Oct-87 1422 Common-Lisp-Object-System-mailer comments on portions of the Oct 26 10:05 draft
C00754 00140 ∂02-Nov-87 1330 Common-Lisp-Object-System-mailer :accessor slot option
C00756 00141 ∂02-Nov-87 1417 Common-Lisp-Object-System-mailer Comments on chapter 2
C00764 00142 ∂03-Nov-87 0801 Common-Lisp-Object-System-mailer Comment on the chapter 2.
C00766 00143 ∂03-Nov-87 1045 Common-Lisp-Object-System-mailer Comment on the chapter 2, Version of Nov 2.
C00780 00144 ∂03-Nov-87 1354 Common-Lisp-Object-System-mailer CLOS mailing list
C00782 00145 ∂03-Nov-87 1447 Common-Lisp-Object-System-mailer CLOS mailing list
C00785 00146 ∂03-Nov-87 1512 Common-Lisp-Object-System-mailer Comment on the chapter 2, Version of Nov 2.
C00790 00147 ∂04-Nov-87 1018 Common-Lisp-Object-System-mailer Issues raised by comments on chapter 2
C00800 00148 ∂04-Nov-87 1025 Common-Lisp-Object-System-mailer Lambda-list in Defgeneric
C00801 00149 ∂04-Nov-87 1104 Common-Lisp-Object-System-mailer Issues raised by comments on chapter 2
C00806 00150 ∂04-Nov-87 1210 Common-Lisp-Object-System-mailer method signatures
C00809 00151 ∂04-Nov-87 1647 Common-Lisp-Object-System-mailer Re: Issues raised by comments on chapter 2
C00815 00152 ∂04-Nov-87 1737 Common-Lisp-Object-System-mailer format for description of generic functions in chapter 2
C00833 00153 ∂04-Nov-87 2046 Common-Lisp-Object-System-mailer Re: Comment on the chapter 2, Version of Nov 2.
C00839 00154 ∂05-Nov-87 0919 Common-Lisp-Object-System-mailer lambda-list in defgeneric
C00841 00155 ∂05-Nov-87 0924 Common-Lisp-Object-System-mailer lambda-list in defgeneric, generic-flet, etc.
C00845 00156 ∂05-Nov-87 0950 Common-Lisp-Object-System-mailer format for description of generic functions in chapter 2
C00861 00157 ∂05-Nov-87 1231 Common-Lisp-Object-System-mailer ambiguity in defgeneric and method descriptions
C00865 00158 ∂05-Nov-87 1545 Common-Lisp-Object-System-mailer Re: lambda-list in defgeneric, generic-flet, etc.
C00867 00159 ∂05-Nov-87 1623 Common-Lisp-Object-System-mailer Re: ambiguity in defgeneric and method descriptions
C00872 00160 ∂05-Nov-87 1631 Common-Lisp-Object-System-mailer State of Affairs
C00879 00161 ∂05-Nov-87 1727 Common-Lisp-Object-System-mailer Re: format for description of generic functions in chapter 2
C00886 00162 ∂05-Nov-87 1817 Common-Lisp-Object-System-mailer CALL-NEXT-METHOD example
C00889 00163 ∂05-Nov-87 1927 Common-Lisp-Object-System-mailer CALL-NEXT-METHOD example
C00892 00164 ∂05-Nov-87 1948 Common-Lisp-Object-System-mailer Re: ambiguity in defgeneric and method descriptions
C00897 00165 ∂05-Nov-87 2111 Common-Lisp-Object-System-mailer Chapter 1 typos.
C00899 00166 ∂06-Nov-87 1017 Common-Lisp-Object-System-mailer Defgeneric affects methods?
C00900 00167 ∂06-Nov-87 1109 Common-Lisp-Object-System-mailer CALL-NEXT-METHOD example
C00903 00168 ∂06-Nov-87 1229 Common-Lisp-Object-System-mailer setf of class-name
C00906 00169 ∂06-Nov-87 1343 Common-Lisp-Object-System-mailer Re: Defgeneric affects methods?
C00909 00170 ∂06-Nov-87 1352 Common-Lisp-Object-System-mailer Re: Defgeneric affects methods?
C00912 00171 ∂06-Nov-87 1731 Common-Lisp-Object-System-mailer Re: format for description of generic functions in chapter 2
C00915 00172 ∂09-Nov-87 1452 Common-Lisp-Object-System-mailer Current State of CLOS Draft
C00917 00173 ∂10-Nov-87 1402 Common-Lisp-Object-System-mailer Agenda for X3J13
C00920 00174 ∂11-Nov-87 0757 Common-Lisp-Object-System-mailer Agenda for X3J13
C00924 00175 ∂11-Nov-87 1441 Common-Lisp-Object-System-mailer making gf lambda lists
C00926 00176 ∂11-Nov-87 1451 Common-Lisp-Object-System-mailer scope of call-next-method
C00929 00177 ∂11-Nov-87 1514 Common-Lisp-Object-System-mailer optimization in the spec
C00934 00178 ∂12-Nov-87 1330 Common-Lisp-Object-System-mailer scope of call-next-method
C00937 00179 ∂12-Nov-87 1411 Common-Lisp-Object-System-mailer scope of call-next-method
C00942 00180 ∂12-Nov-87 1411 Common-Lisp-Object-System-mailer scope of call-next-method
C00946 00181 ∂12-Nov-87 1821 Common-Lisp-Object-System-mailer Re: optimization in the spec
C00950 00182 ∂13-Nov-87 0833 Common-Lisp-Object-System-mailer Scope of Call-next-method
C00952 00183 ∂13-Nov-87 1119 Common-Lisp-Object-System-mailer optimization in the spec
C00958 00184 ∂14-Nov-87 1453 Common-Lisp-mailer questions about CLOS [original subject: equality of structures]
C00965 00185 ∂19-Nov-87 1714 Common-Lisp-Object-System-mailer symbol-macrolet
C00968 00186 ∂20-Nov-87 0343 Common-Lisp-Object-System-mailer Re: symbol-macrolet
C00970 00187 ∂20-Nov-87 0944 Common-Lisp-Object-System-mailer Re: symbol-macrolet
C00972 00188 ∂20-Nov-87 1455 Common-Lisp-Object-System-mailer Re: symbol-macrolet
C00974 00189 ∂23-Nov-87 1041 Common-Lisp-Object-System-mailer Re: symbol-macrolet
C00977 00190 ∂23-Nov-87 1220 Common-Lisp-Object-System-mailer symbol-macrolet
C00982 00191 ∂23-Nov-87 1306 Common-Lisp-Object-System-mailer symbol-macrolet
C00989 00192 ∂23-Nov-87 1758 Common-Lisp-Object-System-mailer making gf lambda lists
C00993 00193 ∂24-Nov-87 1144 Common-Lisp-Object-System-mailer Re: making gf lambda lists
C00995 00194 ∂30-Nov-87 1049 Common-Lisp-Object-System-mailer :accessor slot option
C01000 00195 ∂01-Dec-87 2103 Common-Lisp-Object-System-mailer Re: symbol-macrolet
C01004 00196 ∂01-Dec-87 2113 Common-Lisp-Object-System-mailer Re: :accessor slot option
C01009 00197 ∂03-Dec-87 1914 Common-Lisp-Object-System-mailer mop
C01011 00198 ∂04-Dec-87 1754 Common-Lisp-Object-System-mailer the mop
C01012 00199 ∂07-Dec-87 0944 RPG MOP comments part 1.
C01021 00200 ∂07-Dec-87 1643 Common-Lisp-Object-System-mailer MOP comments part 1.
C01031 00201 ∂07-Dec-87 2204 RPG Re: MOP comments part 1.
C01035 00202 ∂08-Dec-87 1555 Common-Lisp-Object-System-mailer MOP Comments Part 2.
C01041 00203 ∂08-Dec-87 2005 Common-Lisp-Object-System-mailer MOP Comments Part 2.
C01046 00204 ∂09-Dec-87 1006 Common-Lisp-Object-System-mailer MOP Comments (Repost)
C01093 00205 ∂09-Dec-87 1246 Common-Lisp-Object-System-mailer MOP Comments (Repost) - 2 3 4 5a
C01107 00206 ∂09-Dec-87 1344 Common-Lisp-Object-System-mailer Re: MOP Comments (Repost) - 2 3 4 5a
C01109 00207 ∂09-Dec-87 1430 Common-Lisp-Object-System-mailer Meeting next week
C01111 00208 ∂09-Dec-87 1456 Common-Lisp-Object-System-mailer Re: MOP Comments (Repost) - 2 3 4 5a
C01120 00209 ∂09-Dec-87 1917 Common-Lisp-Object-System-mailer Re: MOP Comments (Repost) - 2 3 4 5a
C01127 00210 ∂10-Dec-87 1739 Common-Lisp-Object-System-mailer Re: Meeting next week
C01131 00211 ∂11-Dec-87 1108 Common-Lisp-Object-System-mailer Re: Meeting next week
C01133 00212 ∂11-Dec-87 1300 Common-Lisp-Object-System-mailer Re: Meeting next week
C01135 00213 ∂11-Dec-87 1355 Common-Lisp-Object-System-mailer new version of mop
C01136 00214 ∂11-Dec-87 1725 Common-Lisp-Object-System-mailer Meeting Next Week
C01148 00215 ∂12-Dec-87 0128 Common-Lisp-Object-System-mailer Meeting Next Week
C01153 00216 ∂12-Dec-87 1235 Common-Lisp-Object-System-mailer Comments on MOP
C01162 00217 ∂13-Dec-87 2138 Common-Lisp-Object-System-mailer Further Reaction to MOP
C01172 00218 ∂14-Dec-87 0727 Common-Lisp-Object-System-mailer meeting next week
C01177 00219 ∂14-Dec-87 2109 Common-Lisp-Object-System-mailer new version of mop
C01179 00220 ∂15-Dec-87 1004 Common-Lisp-Object-System-mailer
C01180 00221 ∂18-Dec-87 1558 Common-Lisp-Object-System-mailer MOP Goals
C01183 00222 ∂18-Dec-87 1609 Common-Lisp-Object-System-mailer Versioning
C01186 00223 ∂19-Dec-87 0925 Common-Lisp-Object-System-mailer Versioning
C01189 00224 ∂19-Dec-87 1047 Common-Lisp-Object-System-mailer Re: Versioning
C01193 00225 ∂19-Dec-87 1059 Common-Lisp-Object-System-mailer MOP and Inheritance
C01196 00226 ∂19-Dec-87 1100 Common-Lisp-Object-System-mailer Re: Versioning
C01200 00227 ∂21-Dec-87 1953 Common-Lisp-Object-System-mailer MOP and Inheritance
C01202 00228 ∂22-Dec-87 1514 Common-Lisp-Object-System-mailer Re: MOP and Inheritance
C01206 00229 ∂22-Dec-87 1819 Common-Lisp-Object-System-mailer with-accessors
C01208 00230 ∂23-Dec-87 1307 Common-Lisp-Object-System-mailer add-method when method exists
C01211 00231 ∂23-Dec-87 1436 Common-Lisp-Object-System-mailer New Class Organization for CLOS Kernel
C01215 00232 ∂23-Dec-87 1444 Common-Lisp-Object-System-mailer reinitialize-instance
C01217 00233 ∂23-Dec-87 1454 Common-Lisp-Object-System-mailer Concep.tex
C01218 00234 ∂23-Dec-87 1458 Common-Lisp-Object-System-mailer Proposed New Outline For MOP Kernel
C01222 00235 ∂23-Dec-87 1539 Common-Lisp-Object-System-mailer New Specializers For CLOS
C01228 00236 ∂24-Dec-87 1638 Common-Lisp-Object-System-mailer CALL-NEXT-METHOD Winter Solstice present
C01233 00237 ∂28-Dec-87 0631 Common-Lisp-Object-System-mailer Re: add-method when method exists
C01236 00238 ∂28-Dec-87 0632 Common-Lisp-Object-System-mailer Re: add-method when method exists
C01239 00239 ∂28-Dec-87 0903 Common-Lisp-Object-System-mailer CALL-NEXT-METHOD Winter Solstice present
C01246 00240 ∂28-Dec-87 1053 Common-Lisp-Object-System-mailer Re: CALL-NEXT-METHOD Winter Solstice present
C01252 00241 ∂28-Dec-87 1053 Common-Lisp-Object-System-mailer Re: New Specializers For CLOS
C01256 00242 ∂28-Dec-87 1053 Common-Lisp-Object-System-mailer Re: with-accessors
C01259 00243 ∂28-Dec-87 1108 Common-Lisp-Object-System-mailer Re: CALL-NEXT-METHOD Winter Solstice present
C01263 00244 ∂28-Dec-87 1129 Common-Lisp-Object-System-mailer with-accessors
C01265 00245 ∂28-Dec-87 1204 Common-Lisp-Object-System-mailer Re: add-method when method exists
C01272 00246 ∂28-Dec-87 1252 Common-Lisp-Object-System-mailer New Class Organization for CLOS Kernel
C01277 00247 ∂28-Dec-87 1316 Common-Lisp-Object-System-mailer with-accessors
C01280 00248 ∂28-Dec-87 1359 Common-Lisp-Object-System-mailer partial results of Cambridge meeting
C01287 00249 ∂28-Dec-87 1851 Common-Lisp-Object-System-mailer Comments on Chapter 1
C01303 00250 ∂28-Dec-87 1947 Common-Lisp-Object-System-mailer Standardizing the macroexpansion of make-method-call
C01315 00251 ∂29-Dec-87 1435 Common-Lisp-Object-System-mailer Method Combination Objects
C01332 00252 ∂29-Dec-87 1435 Common-Lisp-Object-System-mailer Method Combination Objects
C01348 00253 ∂30-Dec-87 0924 Common-Lisp-Object-System-mailer Comments on Chapter 2
C01372 00254 ∂04-Jan-88 1510 Common-Lisp-Object-System-mailer Re: with-accessors
C01375 00255 ∂05-Jan-88 1243 Common-Lisp-Object-System-mailer New Class Organization for CLOS Kernel
C01381 00256 ∂05-Jan-88 1256 Common-Lisp-Object-System-mailer Standardizing the macroexpansion of make-method-call
C01385 00257 ∂06-Jan-88 1313 Common-Lisp-Object-System-mailer Re: New Specializers For CLOS
C01390 00258 ∂07-Jan-88 1055 Common-Lisp-Object-System-mailer CALL-NEXT-METHOD
C01392 00259 ∂07-Jan-88 1502 Common-Lisp-Object-System-mailer Re: CALL-NEXT-METHOD
C01395 00260 ∂07-Jan-88 1652 Common-Lisp-Object-System-mailer Chapter 3 and the Cambridge Meeting
C01399 00261 ∂07-Jan-88 1835 Common-Lisp-Object-System-mailer CALL-NEXT-METHOD
C01403 00262 ∂11-Jan-88 1652 Common-Lisp-Object-System-mailer call-method proposal
C01409 00263 ∂11-Jan-88 1802 Common-Lisp-Object-System-mailer CALL-NEXT-METHOD
C01414 00264 ∂11-Jan-88 1917 Common-Lisp-Object-System-mailer call-method proposal prime
C01420 00265 ∂11-Jan-88 2121 Common-Lisp-Object-System-mailer call-method proposal prime prime
C01427 00266 ∂11-Jan-88 2212 Common-Lisp-Object-System-mailer call-method proposal prime prime
C01434 00267 ∂12-Jan-88 2006 Common-Lisp-Object-System-mailer defmethod-setf
C01436 00268 ∂12-Jan-88 2215 Common-Lisp-Object-System-mailer CALL-NEXT-METHOD and funcall-qua/send-as
C01440 00269 ∂13-Jan-88 0821 Common-Lisp-Object-System-mailer is the functi.dvi file trashed?
C01442 00270 ∂13-Jan-88 0926 Common-Lisp-Object-System-mailer Re: defmethod-setf
C01445 00271 ∂13-Jan-88 1003 Common-Lisp-Object-System-mailer Re: defmethod-setf
C01448 00272 ∂13-Jan-88 1009 Common-Lisp-Object-System-mailer defmethod-setf
C01449 00273 ∂13-Jan-88 1038 Common-Lisp-Object-System-mailer Re: Method Combination Objects
C01456 00274 ∂13-Jan-88 1240 Common-Lisp-Object-System-mailer Defmethod-setf
C01458 00275 ∂13-Jan-88 1437 Common-Lisp-Object-System-mailer functi.dvi
C01459 00276 ∂13-Jan-88 1716 Common-Lisp-Object-System-mailer Sonya's problem with functi.dvi
C01461 00277 ∂14-Jan-88 0656 Common-Lisp-Object-System-mailer Re: add-method when method exists
C01464 00278 ∂14-Jan-88 2008 Common-Lisp-Object-System-mailer Re: Method Combination Objects
C01467 00279 ∂14-Jan-88 2008 Common-Lisp-Object-System-mailer call-method proposal prime prime
C01474 00280 ∂14-Jan-88 2008 Common-Lisp-Object-System-mailer Standardizing the macroexpansion of make-method-call
C01479 00281 ∂15-Jan-88 0907 Common-Lisp-Object-System-mailer Re: call-method proposal prime prime
C01484 00282 ∂15-Jan-88 0923 Common-Lisp-Object-System-mailer DEFMETHOD Specification
C01486 00283 ∂15-Jan-88 1315 Common-Lisp-Object-System-mailer method-lambda
C01491 00284 ∂15-Jan-88 1333 Common-Lisp-Object-System-mailer Re: call-method proposal prime prime
C01500 00285 ∂15-Jan-88 1356 Common-Lisp-Object-System-mailer Re: call-method proposal prime prime
C01502 00286 ∂15-Jan-88 1356 Common-Lisp-Object-System-mailer Re: Method Combination Objects
C01506 00287 ∂15-Jan-88 1421 Common-Lisp-Object-System-mailer Alternative Proposal for class updating
C01512 00288 ∂15-Jan-88 2050 Common-Lisp-Object-System-mailer DEFMETHOD Specification
C01515 00289 ∂18-Jan-88 1803 Common-Lisp-Object-System-mailer add-method
C01517 00290 ∂19-Jan-88 0213 Common-Lisp-Object-System-mailer Object Lisp vs CLOS in BYTE (Jan 88)
C01520 00291 ∂19-Jan-88 0846 Common-Lisp-Object-System-mailer some questions on your chapter 2 comments
C01525 00292 ∂19-Jan-88 0939 Common-Lisp-Object-System-mailer Re: some questions on your chapter 2 comments
C01527 00293 ∂19-Jan-88 1255 Common-Lisp-Object-System-mailer Re: some questions on your chapter 2 comments
C01530 00294 ∂19-Jan-88 1317 Common-Lisp-Object-System-mailer Re: add-method
C01533 00295 ∂19-Jan-88 1546 Common-Lisp-Object-System-mailer Re: some questions on your chapter 2 comments
C01536 00296 ∂21-Jan-88 1130 Common-Lisp-Object-System-mailer METHOD-LAMBDA and Removing parsing
C01538 00297 ∂21-Jan-88 1132 Common-Lisp-Object-System-mailer Re: CALL-NEXT-METHOD and funcall-qua/send-as
C01541 00298 ∂21-Jan-88 1428 Common-Lisp-Object-System-mailer Remarks
C01548 00299 ∂21-Jan-88 1609 Common-Lisp-Object-System-mailer Remarks
C01552 00300 ∂21-Jan-88 1646 Common-Lisp-Object-System-mailer ADD-METHOD
C01554 00301 ∂21-Jan-88 1751 Common-Lisp-Object-System-mailer functi
C01555 00302 ∂21-Jan-88 1844 Common-Lisp-Object-System-mailer Re: ADD-METHOD
C01557 00303 ∂22-Jan-88 1303 Common-Lisp-Object-System-mailer ADD-METHOD
C01559 00304 ∂23-Jan-88 0725 Common-Lisp-Object-System-mailer Re: New Class Organization for CLOS Kernel
C01568 00305 ∂23-Jan-88 0810 Common-Lisp-Object-System-mailer Re: Class organization for CLOS kernel
C01577 00306 ∂25-Jan-88 1349 Common-Lisp-Object-System-mailer Comments on latest draft documents
C01587 00307 ∂25-Jan-88 1648 Common-Lisp-Object-System-mailer Alternative Proposal for class updating
C01592 00308 ∂25-Jan-88 1918 Common-Lisp-Object-System-mailer Type-checking of slot values
C01596 00309 ∂26-Jan-88 0137 Common-Lisp-Object-System-mailer Type-checking of slot values
C01603 00310 ∂26-Jan-88 0832 Common-Lisp-Object-System-mailer Type-checking of slot values
C01606 00311 ∂26-Jan-88 0848 Common-Lisp-Object-System-mailer Re: Type-checking of slot values
C01615 00312 ∂26-Jan-88 1335 Common-Lisp-Object-System-mailer Re: Type-checking of slot values
C01619 00313 ∂26-Jan-88 1344 Common-Lisp-Object-System-mailer Re: Type-checking of slot values
C01623 00314 ∂26-Jan-88 1438 Common-Lisp-Object-System-mailer Re: Type-checking of slot values
C01628 00315 ∂26-Jan-88 1809 Common-Lisp-Object-System-mailer Type-checking of slot values
C01638 00316 ∂26-Jan-88 1848 Common-Lisp-Object-System-mailer Re: Type-checking of slot values
C01642 00317 ∂27-Jan-88 0318 Common-Lisp-Object-System-mailer Type-checking of slot values
C01646 00318 ∂27-Jan-88 0934 Common-Lisp-Object-System-mailer Method Combination Objects
C01666 00319 ∂27-Jan-88 1123 Common-Lisp-Object-System-mailer Method Combination Objects
C01674 00320 ∂27-Jan-88 1301 Common-Lisp-Object-System-mailer Method Combination Objects
C01680 00321 ∂27-Jan-88 1325 Common-Lisp-Object-System-mailer Re: Type-checking of slot values
C01685 00322 ∂27-Jan-88 1358 Common-Lisp-Object-System-mailer Re: Method Combination Objects
C01688 00323 ∂27-Jan-88 1746 Common-Lisp-Object-System-mailer Re: Method Combination Objects
C01692 00324 ∂27-Jan-88 2015 Common-Lisp-Object-System-mailer call-method proposal prime prime
C01712 00325 ∂27-Jan-88 2128 Common-Lisp-Object-System-mailer Typechecking
C01715 00326 ∂28-Jan-88 0345 Common-Lisp-Object-System-mailer Type-checking of slot values
C01718 00327 ∂28-Jan-88 0803 Common-Lisp-Object-System-mailer Re: Method Combination Objects
C01721 00328 ∂28-Jan-88 0804 Common-Lisp-Object-System-mailer call-method proposal
C01724 00329 ∂28-Jan-88 0911 Common-Lisp-Object-System-mailer Method Combination Objects
C01743 00330 ∂28-Jan-88 1147 Common-Lisp-Object-System-mailer reinitialization protocol
C01747 00331 ∂28-Jan-88 1152 Common-Lisp-Object-System-mailer class updating protocol
C01754 00332 ∂28-Jan-88 1804 Common-Lisp-Object-System-mailer call-method proposal prime prime
C01757 00333 ∂28-Jan-88 1838 Common-Lisp-Object-System-mailer call-method proposal prime prime
C01760 00334 ∂29-Jan-88 0800 Common-Lisp-Object-System-mailer Re: class updating protocol
C01766 00335 ∂29-Jan-88 0905 Common-Lisp-Object-System-mailer Re: reinitialization protocol
C01768 00336 ∂29-Jan-88 0927 Common-Lisp-Object-System-mailer Re: class updating protocol
C01771 00337 ∂29-Jan-88 1106 Common-Lisp-Object-System-mailer Re: Comments on latest draft documents
C01777 00338 ∂29-Jan-88 1134 Common-Lisp-Object-System-mailer Re: reinitialization protocol
C01780 00339 ∂29-Jan-88 1146 Common-Lisp-Object-System-mailer Re: class updating protocol
C01783 00340 ∂29-Jan-88 1151 Common-Lisp-Object-System-mailer Re: reinitialization protocol
C01786 00341 ∂29-Jan-88 1247 Common-Lisp-Object-System-mailer call-method proposal prime prime
C01790 00342 ∂29-Jan-88 1331 Common-Lisp-Object-System-mailer Re: class updating protocol
C01793 00343 ∂29-Jan-88 1903 Common-Lisp-Object-System-mailer Re: Comments on latest draft documents
C01797 00344 ∂30-Jan-88 0955 Common-Lisp-Object-System-mailer Remarks about Comments on Latest Draft Documents
C01804 00345 ∂30-Jan-88 2128 Common-Lisp-Object-System-mailer Chapter 1
C01805 00346 ∂31-Jan-88 1622 Common-Lisp-Object-System-mailer Chapter 2
C01806 00347 ∂01-Feb-88 1457 Common-Lisp-Object-System-mailer Re: Remarks about Comments on Latest Draft Documents
C01809 00348 ∂02-Feb-88 1032 Common-Lisp-Object-System-mailer Comments on most recent draft: Chap 1 and 2
C01817 00349 ∂02-Feb-88 1401 Common-Lisp-Object-System-mailer Class Names (Again! Can't We Ever Stop?)
C01820 00350 ∂02-Feb-88 1818 Common-Lisp-Object-System-mailer Re: Class Names (Again! Can't We Ever Stop?)
C01824 00351 ∂02-Feb-88 2040 Common-Lisp-Object-System-mailer Names, Names
C01825 00352 ∂03-Feb-88 0757 Common-Lisp-Object-System-mailer Chapter 1
C01827 00353 ∂03-Feb-88 0757 Common-Lisp-Object-System-mailer Chapter 2
C01829 00354 ∂03-Feb-88 1022 Common-Lisp-Object-System-mailer Re: Names, Names
C01832 00355 ∂03-Feb-88 1449 Common-Lisp-Object-System-mailer Re: Names, Names
C01834 00356 ∂03-Feb-88 1532 Common-Lisp-Object-System-mailer Comments on most recent draft: Chap 1 and 2
C01838 00357 ∂03-Feb-88 1822 Common-Lisp-Object-System-mailer Re: Comments on most recent draft: Chap 1 and 2
C01841 00358 ∂03-Feb-88 2235 Common-Lisp-Object-System-mailer Names
C01844 00359 ∂04-Feb-88 1530 Common-Lisp-Object-System-mailer Comments on most recent draft: Chap 1 and 2
C01847 00360 ∂04-Feb-88 1631 Common-Lisp-Object-System-mailer Naming
C01848 00361 ∂04-Feb-88 1653 Common-Lisp-Object-System-mailer Re: Naming
C01850 00362 ∂04-Feb-88 1714 Common-Lisp-Object-System-mailer Re: Naming
C01853 00363 ∂05-Feb-88 0839 Common-Lisp-Object-System-mailer Re: Naming
C01856 00364 ∂05-Feb-88 0948 Common-Lisp-Object-System-mailer CONCEP and FUNCTI
C01857 00365 ∂05-Feb-88 1042 Common-Lisp-Object-System-mailer Re: Naming
C01861 00366 ∂05-Feb-88 1048 Common-Lisp-Object-System-mailer Re: Naming
C01865 00367 ∂05-Feb-88 1101 Common-Lisp-Object-System-mailer Re: Type-checking of slot values
C01868 00368 ∂05-Feb-88 1140 Common-Lisp-Object-System-mailer Typechecking
C01874 00369 ∂05-Feb-88 1141 Common-Lisp-Object-System-mailer Typechecking
C01880 00370 ∂05-Feb-88 1230 Common-Lisp-Object-System-mailer Typechecking
C01881 00371 ∂05-Feb-88 1310 Common-Lisp-Object-System-mailer Re: Typechecking
C01883 00372 ∂05-Feb-88 1334 Common-Lisp-Object-System-mailer defgeneric :method option
C01897 00373 ∂05-Feb-88 1936 Common-Lisp-Object-System-mailer Re: Typechecking
C01899 00374 ∂05-Feb-88 2205 Common-Lisp-Object-System-mailer Defgeneric
C01901 00375 ∂06-Feb-88 1034 Common-Lisp-Object-System-mailer Re: Typechecking
C01903 00376 ∂06-Feb-88 1146 Common-Lisp-Object-System-mailer DEFGENERIC
C01904 00377 ∂06-Feb-88 2218 Common-Lisp-Object-System-mailer Typechecking
C01907 00378 ∂07-Feb-88 1228 Common-Lisp-Object-System-mailer Typechecking
C01909 00379 ∂07-Feb-88 1722 Common-Lisp-Object-System-mailer Chapter 2
C01910 00380 ∂07-Feb-88 1800 Common-Lisp-Object-System-mailer Chapter 1
C01911 00381 ∂07-Feb-88 1906 Common-Lisp-Object-System-mailer Typechecking
C01916 00382 ∂08-Feb-88 0901 Common-Lisp-Object-System-mailer Re: defgeneric :method option
C01919 00383 ∂08-Feb-88 0902 Common-Lisp-Object-System-mailer Re: defgeneric :method option
C01922 00384 ∂08-Feb-88 0913 Common-Lisp-Object-System-mailer DEFGENERIC
C01925 00385 ∂08-Feb-88 1017 Common-Lisp-Object-System-mailer CONCEP and FUNCTI
C01929 00386 ∂08-Feb-88 1021 Common-Lisp-Object-System-mailer Re: defgeneric :method option
C01933 00387 ∂08-Feb-88 1033 Common-Lisp-Object-System-mailer Comments on most recent draft: Chap 1 and 2
C01936 00388 ∂08-Feb-88 1613 Common-Lisp-Object-System-mailer x3j13 draft
C01937 00389 ∂08-Feb-88 1619 Common-Lisp-Object-System-mailer Re: defgeneric :method option
C01939 00390 ∂08-Feb-88 1636 Common-Lisp-Object-System-mailer Re: defgeneric :method option
C01941 00391 ∂10-Feb-88 0019 Common-Lisp-Object-System-mailer Comments on most recent draft: Chap 1 and 2
C01946 00392 ∂10-Feb-88 0858 Common-Lisp-Object-System-mailer Status of SETF functions in Common Lisp
C01952 00393 ∂11-Feb-88 1001 Common-Lisp-Object-System-mailer Re: Status of SETF functions in Common Lisp
C01955 00394 ∂11-Feb-88 1437 Common-Lisp-Object-System-mailer Comments on most recent draft: Chap 1 and 2
C01959 00395 ∂12-Feb-88 0018 Common-Lisp-Object-System-mailer Status of SETF functions in Common Lisp
C01962 00396 ∂12-Feb-88 1517 Common-Lisp-Object-System-mailer Issue: SETF-SUB-METHODS
C01980 00397 ∂12-Feb-88 2320 Common-Lisp-Object-System-mailer Issue: SETF-SUB-METHODS
C01982 00398 ∂15-Feb-88 1548 Common-Lisp-Object-System-mailer 88-002 question
C01984 00399 ∂15-Feb-88 1626 Common-Lisp-Object-System-mailer 88-002 Comment
C01986 00400 ∂15-Feb-88 1701 Common-Lisp-Object-System-mailer Method Combination
C01987 00401 ∂15-Feb-88 1705 Common-Lisp-Object-System-mailer SLOT-BOUNDP
C01989 00402 ∂08-Mar-88 1510 Common-Lisp-Object-System-mailer new version of mop
C01991 00403 ∂09-Mar-88 0436 Common-Lisp-Object-System-mailer Re: new version of mop
C01993 00404 ∂09-Mar-88 0903 Common-Lisp-Object-System-mailer Small omission in Chap 2
C01996 00405 ∂09-Mar-88 1006 Common-Lisp-Object-System-mailer Small omission in Chap 2
C02000 00406 ∂09-Mar-88 1843 Common-Lisp-Object-System-mailer CLOS Consortium
C02004 00407 ∂11-Mar-88 1215 Common-Lisp-Object-System-mailer new version of mopc
C02006 00408 ∂18-Mar-88 1746 Common-Lisp-Object-System-mailer Proposed Wording Change to the Error Terminology
C02009 00409 ∂21-Mar-88 0905 Common-Lisp-Object-System-mailer Proposed Wording PicoChange to the Error Terminology
C02012 00410 ∂21-Mar-88 0810 Common-Lisp-mailer CLOS Status
C02014 00411 ∂21-Mar-88 1115 Common-Lisp-Object-System-mailer Proposed Wording PicoChange to the Error Terminology
C02015 00412 ∂21-Mar-88 1245 Common-Lisp-Object-System-mailer Proposed Wording Change to the Error Terminology
C02019 00413 ∂21-Mar-88 1303 Common-Lisp-Object-System-mailer Re: Proposed Wording Change to the Error Terminology
C02021 00414 ∂21-Mar-88 1329 Common-Lisp-Object-System-mailer Proposed Wording Change to the Error Terminology (II)
C02023 00415 ∂21-Mar-88 1436 Common-Lisp-Object-System-mailer Proposed Wording Change to the Error Terminology (II)
C02027 00416 ∂21-Mar-88 1628 Common-Lisp-Object-System-mailer Proposed Wording Change to the Error Terminology (II)
C02030 00417 ∂22-Mar-88 0018 Common-Lisp-Object-System-mailer Proposed Wording Change to the Error Terminology (II)
C02033 00418 ∂22-Mar-88 0811 Common-Lisp-Object-System-mailer Error Terminology
C02040 00419 ∂22-Mar-88 1323 Common-Lisp-Object-System-mailer Error Terminology
C02043 00420 ∂23-Mar-88 1006 Common-Lisp-Object-System-mailer Some early comments on 88-003
C02055 00421 ∂23-Mar-88 1204 Common-Lisp-Object-System-mailer Error Terminology
C02059 00422 ∂23-Mar-88 1314 Common-Lisp-Object-System-mailer D'4 Example
C02063 00423 ∂23-Mar-88 1359 Common-Lisp-Object-System-mailer D'4 Example
C02066 00424 ∂23-Mar-88 1419 Common-Lisp-Object-System-mailer D'4 Example
C02071 00425 ∂23-Mar-88 1454 Common-Lisp-Object-System-mailer Undefined
C02072 00426 ∂24-Mar-88 1855 Common-Lisp-Object-System-mailer Error Terminology
C02075 00427 ∂24-Mar-88 2155 Common-Lisp-Object-System-mailer Error Terminology
C02079 00428 ∂25-Mar-88 0757 Common-Lisp-Object-System-mailer Ch3
C02081 00429 ∂25-Mar-88 1338 Common-Lisp-Object-System-mailer Method-lambda and apply-method-lambda
C02087 00430 ∂25-Mar-88 1351 Common-Lisp-Object-System-mailer Re: Method-lambda and apply-method-lambda
C02090 00431 ∂25-Mar-88 1810 Common-Lisp-Object-System-mailer Re: Error Terminology
C02091 00432 ∂28-Mar-88 1045 Common-Lisp-Object-System-mailer Re: Method-lambda and apply-method-lambda
C02095 00433 ∂28-Mar-88 1142 Common-Lisp-Object-System-mailer Method-lambda and apply-method-lambda
C02099 00434 ∂30-Mar-88 2055 Common-Lisp-Object-System-mailer Error Terminology
C02105 00435 ∂31-Mar-88 1355 Common-Lisp-Object-System-mailer Error Terminology
C02109 00436 ∂04-Apr-88 0541 Common-Lisp-Object-System-mailer CLOS, and slot hiding.
C02114 00437 ∂04-Apr-88 0843 Common-Lisp-Object-System-mailer Re: CLOS, and slot hiding.
C02119 00438 ∂04-Apr-88 0916 Common-Lisp-Object-System-mailer Method-lambda and apply-method-lambda
C02127 00439 ∂04-Apr-88 1522 Common-Lisp-Object-System-mailer add-named-xxx
C02134 00440 ∂04-Apr-88 1631 Common-Lisp-Object-System-mailer Some early comments on 88-003 (accessor methods)
C02138 00441 ∂04-Apr-88 1632 Common-Lisp-Object-System-mailer update-instance-structure
C02140 00442 ∂05-Apr-88 1746 Common-Lisp-Object-System-mailer (re)initialization revisited
C02151 00443 ∂05-Apr-88 1957 Common-Lisp-Object-System-mailer comments from Kathy Chapman
C02154 00444 ∂06-Apr-88 0905 Common-Lisp-Object-System-mailer Re: CLOS, and slot hiding.
C02161 00445 ∂06-Apr-88 0938 Common-Lisp-Object-System-mailer Re: CLOS, and slot hiding.
C02168 00446 ∂06-Apr-88 0939 Common-Lisp-Object-System-mailer Re: CLOS, and slot hiding.
C02174 00447 ∂06-Apr-88 1015 Common-Lisp-Object-System-mailer Re: CLOS, and slot hiding.
C02176 00448 ∂06-Apr-88 1043 Common-Lisp-Object-System-mailer Reinitialization
C02182 00449 ∂06-Apr-88 1047 Common-Lisp-Object-System-mailer Re: CLOS, and slot hiding.
C02185 00450 ∂06-Apr-88 1253 Common-Lisp-Object-System-mailer Reinitialization
C02191 00451 ∂06-Apr-88 1940 Common-Lisp-Object-System-mailer Reinitialization
C02193 00452 ∂07-Apr-88 1011 Common-Lisp-Object-System-mailer Re: Reinitialization
C02197 00453 ∂07-Apr-88 1040 Common-Lisp-Object-System-mailer Re: Reinitialization
C02203 00454 ∂07-Apr-88 1221 Common-Lisp-Object-System-mailer Re: (re)initialization revisited
C02209 00455 ∂07-Apr-88 1451 Common-Lisp-Object-System-mailer Reinitialization
C02217 00456 ∂07-Apr-88 1917 Common-Lisp-Object-System-mailer Re: (re)initialization revisited
C02220 00457 ∂07-Apr-88 1917 Common-Lisp-Object-System-mailer Reinitialization
C02222 00458 ∂08-Apr-88 0135 Common-Lisp-Object-System-mailer update-instance-structure
C02225 00459 ∂08-Apr-88 0548 Common-Lisp-Object-System-mailer Re: CLOS, and slot hiding.
C02231 00460 ∂08-Apr-88 0638 Common-Lisp-Object-System-mailer Re: CLOS, and slot hiding.
C02236 00461 ∂08-Apr-88 0849 Common-Lisp-Object-System-mailer Re: (re)initialization revisited
C02240 00462 ∂08-Apr-88 0924 Common-Lisp-Object-System-mailer Re: CLOS, and slot hiding.
C02243 00463 ∂08-Apr-88 0950 Common-Lisp-Object-System-mailer Re: Method-lambda and apply-method-lambda
C02251 00464 ∂08-Apr-88 1002 Common-Lisp-Object-System-mailer Re: Method-lambda and apply-method-lambda
C02259 00465 ∂08-Apr-88 1044 Common-Lisp-Object-System-mailer comments on CLOS draft 88-2
C02265 00466 ∂08-Apr-88 1102 Common-Lisp-Object-System-mailer comments on CLOS draft 88-2
C02267 00467 ∂08-Apr-88 1142 Common-Lisp-Object-System-mailer Re: comments on CLOS draft 88-2
C02270 00468 ∂08-Apr-88 1148 Common-Lisp-Object-System-mailer Re: comments on CLOS draft 88-2
C02273 00469 ∂08-Apr-88 1152 Common-Lisp-Object-System-mailer add-named-xxx
C02281 00470 ∂08-Apr-88 1211 Common-Lisp-Object-System-mailer Re: Reinitialization
C02287 00471 ∂08-Apr-88 1314 Common-Lisp-Object-System-mailer comments on CLOS draft 88-2
C02290 00472 ∂08-Apr-88 1514 Common-Lisp-Object-System-mailer method-lambda and apply-method-lambda
C02310 00473 ∂08-Apr-88 1540 Common-Lisp-Object-System-mailer Re: (re)initialization revisited
C02319 00474 ∂09-Apr-88 0337 Common-Lisp-Object-System-mailer add-named-xxx
C02323 00475 ∂11-Apr-88 0906 Common-Lisp-Object-System-mailer Re: method-lambda and apply-method-lambda
C02327 00476 ∂11-Apr-88 1057 Common-Lisp-Object-System-mailer Re: method-lambda and apply-method-lambda
C02332 00477 ∂11-Apr-88 1146 Common-Lisp-Object-System-mailer dependent update protocol
C02345 00478 ∂11-Apr-88 1218 Common-Lisp-Object-System-mailer lattice of kernel classes
C02348 00479 ∂11-Apr-88 1250 Common-Lisp-Object-System-mailer dependent update protocol
C02358 00480 ∂11-Apr-88 1335 Common-Lisp-Object-System-mailer Re: lattice of kernel classes
C02361 00481 ∂11-Apr-88 1320 Common-Lisp-Object-System-mailer Re: lattice of kernel classes
C02365 00482 ∂11-Apr-88 1344 Common-Lisp-Object-System-mailer method-lambda and apply-method-lambda
C02368 00483 ∂11-Apr-88 1410 Common-Lisp-Object-System-mailer method-lambda and apply-method-lambda
C02372 00484 ∂11-Apr-88 1441 Common-Lisp-Object-System-mailer Re: method-lambda and apply-method-lambda
C02381 00485 ∂11-Apr-88 1624 Common-Lisp-Object-System-mailer method-lambda and apply-method-lambda
C02389 00486 ∂11-Apr-88 1604 Common-Lisp-Object-System-mailer Re: method-lambda and apply-method-lambda
C02404 00487 ∂11-Apr-88 1739 Common-Lisp-Object-System-mailer Reinitialization
C02420 00488 ∂11-Apr-88 1755 Common-Lisp-Object-System-mailer method-lambda and apply-method-lambda
C02424 00489 ∂12-Apr-88 0859 Common-Lisp-Object-System-mailer two questions about standard-class
C02427 00490 ∂12-Apr-88 1027 Common-Lisp-Object-System-mailer method-lambda and apply-method-lambda
C02437 00491 ∂12-Apr-88 1502 Common-Lisp-Object-System-mailer Re: Reinitialization
C02441 00492 ∂12-Apr-88 1520 Common-Lisp-Object-System-mailer Re: Reinitialization
C02443 00493 ∂12-Apr-88 1748 Common-Lisp-Object-System-mailer Re: Reinitialization
C02446 00494 ∂12-Apr-88 1835 Common-Lisp-Object-System-mailer Re: Reinitialization
C02449 00495 ∂13-Apr-88 0809 Common-Lisp-Object-System-mailer Announcing New Journal on Object-Oriented Programming
C02452 00496 ∂13-Apr-88 0848 Common-Lisp-Object-System-mailer Re: method-lambda and apply-method-lambda
C02458 00497 ∂13-Apr-88 1010 Common-Lisp-Object-System-mailer two questions about standard-class
C02464 00498 ∂13-Apr-88 1029 Common-Lisp-Object-System-mailer Re: MAKE-METHOD-FUNCTION and APPLY-METHOD
C02476 00499 ∂13-Apr-88 1032 Common-Lisp-Object-System-mailer corrections to Chapter 1
C02480 00500 ∂13-Apr-88 1054 Common-Lisp-Object-System-mailer Re: two questions about standard-class
C02486 00501 ∂13-Apr-88 1123 Common-Lisp-Object-System-mailer Re: Reinitialization
C02501 00502 ∂13-Apr-88 1132 Common-Lisp-Object-System-mailer Re: MAKE-METHOD-FUNCTION and APPLY-METHOD
C02505 00503 ∂13-Apr-88 1145 Common-Lisp-Object-System-mailer add-named-xxx
C02508 00504 ∂13-Apr-88 1318 Common-Lisp-Object-System-mailer Chapter 1 and 2 Last Chance Review
C02514 00505 ∂13-Apr-88 1344 Common-Lisp-Object-System-mailer add-named-xxx
C02518 00506 ∂13-Apr-88 1414 Common-Lisp-Object-System-mailer Chapter 1 and 2 Last Chance Review
C02528 00507 ∂13-Apr-88 1435 Common-Lisp-Object-System-mailer Re: Chapter 1 and 2 Last Chance Review
C02531 00508 ∂13-Apr-88 1714 Common-Lisp-Object-System-mailer Re: MAKE-METHOD-FUNCTION and APPLY-METHOD
C02544 00509 ∂14-Apr-88 0607 Common-Lisp-Object-System-mailer promises
C02546 00510 ∂14-Apr-88 0630 Common-Lisp-Object-System-mailer Re: Chapter 1 and 2 Last Chance Review
C02550 00511 ∂14-Apr-88 0950 Common-Lisp-Object-System-mailer promises
C02553 00512 ∂14-Apr-88 1021 Common-Lisp-Object-System-mailer Re: promises
C02555 00513 ∂14-Apr-88 1130 Common-Lisp-Object-System-mailer CLOS consortium
C02557 00514 ∂14-Apr-88 1135 Common-Lisp-Object-System-mailer Responses
C02558 00515 ∂14-Apr-88 1147 Common-Lisp-Object-System-mailer Re: dependent update protocol
C02566 00516 ∂14-Apr-88 1202 Common-Lisp-Object-System-mailer Re: MAKE-METHOD-FUNCTION and APPLY-METHOD
C02571 00517 ∂14-Apr-88 1352 Common-Lisp-Object-System-mailer Re: MAKE-METHOD-FUNCTION and APPLY-METHOD
C02575 00518 ∂14-Apr-88 1431 Common-Lisp-Object-System-mailer Re: MAKE-METHOD-FUNCTION and APPLY-METHOD
C02580 00519 ∂14-Apr-88 1514 Common-Lisp-Object-System-mailer Re: method-lambda and apply-method-lambda
C02586 00520 ∂15-Apr-88 1046 Common-Lisp-Object-System-mailer Comment on CLOS
C02598 00521 ∂15-Apr-88 1345 Common-Lisp-Object-System-mailer CLOS comments
C02603 00522 ∂19-Apr-88 1610 Common-Lisp-Object-System-mailer Re: dependent update protocol
C02605 00523 ∂20-Apr-88 0953 Common-Lisp-Object-System-mailer DEADLINE for finishing 1 and 2
C02607 00524 ∂20-Apr-88 1008 Common-Lisp-Object-System-mailer dependent update protocol
C02614 00525 ∂20-Apr-88 1205 Common-Lisp-Object-System-mailer dependent update protocol
C02619 00526 ∂20-Apr-88 1206 Common-Lisp-Object-System-mailer dependent update protocol
C02624 00527 ∂20-Apr-88 1452 Common-Lisp-Object-System-mailer dependent update protocol
C02638 00528 ∂20-Apr-88 1615 Common-Lisp-Object-System-mailer Re: dependent update protocol
C02642 00529 ∂20-Apr-88 1744 Common-Lisp-Object-System-mailer DEADLINE for finishing 1 and 2
C02645 00530 ∂20-Apr-88 1855 Common-Lisp-Object-System-mailer DEADLINE for finishing 1 and 2
C02648 00531 ∂20-Apr-88 1949 Common-Lisp-Object-System-mailer Re: method-lambda and apply-method-lambda
C02652 00532 ∂20-Apr-88 1954 Common-Lisp-Object-System-mailer comments on CLOS draft 88-2
C02655 00533 ∂20-Apr-88 2012 Common-Lisp-Object-System-mailer dependent update protocol
C02658 00534 ∂20-Apr-88 2025 Common-Lisp-Object-System-mailer Re: Reinitialization
C02662 00535 ∂20-Apr-88 2052 Common-Lisp-Object-System-mailer Re: Reinitialization
C02673 00536 ∂21-Apr-88 0707 Common-Lisp-Object-System-mailer some comments on CLOS
C02679 00537 ∂21-Apr-88 0902 Common-Lisp-Object-System-mailer Sun Opposition To Chapter 3 Hereby Tendered
C02683 00538 ∂21-Apr-88 0920 Common-Lisp-Object-System-mailer Re: dependent update protocol
C02686 00539 ∂21-Apr-88 0920 Common-Lisp-Object-System-mailer Re: dependent update protocol
C02691 00540 ∂25-Apr-88 1223 Common-Lisp-Object-System-mailer Re: Reinitialization
C02694 00541 ∂25-Apr-88 1616 Common-Lisp-Object-System-mailer subcommittee meeting
C02696 00542 ∂25-Apr-88 1700 Common-Lisp-Object-System-mailer reinitialization etc
C02698 00543 ∂26-Apr-88 0956 Common-Lisp-Object-System-mailer Re: Reinitialization
C02703 00544 ∂26-Apr-88 1139 Common-Lisp-Object-System-mailer Re: Reinitialization
C02705 00545 ∂26-Apr-88 1332 Common-Lisp-Object-System-mailer Re: Reinitialization
C02710 00546 ∂26-Apr-88 1557 Common-Lisp-Object-System-mailer X3 subcommittee meeting in June
C02712 00547 ∂26-Apr-88 1846 Common-Lisp-Object-System-mailer dealing with 1+2 comments
C02716 00548 ∂26-Apr-88 1915 Common-Lisp-Object-System-mailer editorial comments
C02730 00549 ∂26-Apr-88 2115 Common-Lisp-Object-System-mailer "Written Responses" to CLOS 88-002: SETF Functions
C02733 00550 ∂26-Apr-88 2131 Common-Lisp-Object-System-mailer "Written Responses" to CLOS 88-002: (Re)Initialization
C02736 00551 ∂26-Apr-88 2131 Common-Lisp-Object-System-mailer "Written Responses" to CLOS 88-002: SYMBOL-CLASS is poorly named
C02746 00552 ∂27-Apr-88 1107 Common-Lisp-Object-System-mailer belated editorial comment
C02749 00553 ∂27-Apr-88 1126 Common-Lisp-Object-System-mailer belated editorial comment
C02753 00554 ∂27-Apr-88 1129 Common-Lisp-Object-System-mailer "Written Responses" to CLOS 88-002: SETF Functions
C02756 00555 ∂27-Apr-88 1345 Common-Lisp-Object-System-mailer Re: "Written Responses" to CLOS 88-002: SYMBOL-CLASS is poorly named
C02759 00556 ∂27-Apr-88 1407 Common-Lisp-Object-System-mailer Editorial Comments and My Disposition of Them
C02771 00557 ∂27-Apr-88 1712 Common-Lisp-Object-System-mailer Re: Reinitialization
C02777 00558 ∂27-Apr-88 1720 Common-Lisp-Object-System-mailer Re: Reinitialization
C02779 00559 ∂28-Apr-88 0933 Common-Lisp-Object-System-mailer Re: Reinitialization
C02785 00560 ∂28-Apr-88 0953 Common-Lisp-Object-System-mailer "Written Responses" to CLOS 88-002: SETF Functions
C02789 00561 ∂29-Apr-88 1417 Common-Lisp-Object-System-mailer type slot option
C02796 00562 ∂29-Apr-88 1425 Common-Lisp-Object-System-mailer documentation slot option
C02800 00563 ∂29-Apr-88 1430 Common-Lisp-Object-System-mailer generic-function special form
C02803 00564 ∂29-Apr-88 1436 Common-Lisp-Object-System-mailer symbol-class is bad name
C02815 00565 ∂29-Apr-88 1436 Common-Lisp-Object-System-mailer no-next-method lexical function
C02820 00566 ∂29-Apr-88 1527 Common-Lisp-Object-System-mailer Re: Reinitialization: check-initargs
C02830 00567 ∂29-Apr-88 1910 Common-Lisp-Object-System-mailer Re: Reinitialization: check-initargs
C02834 00568 ∂30-Apr-88 0156 Common-Lisp-Object-System-mailer type slot option
C02838 00569 ∂30-Apr-88 0316 Common-Lisp-Object-System-mailer FIND-CLASS
C02841 00570 ∂30-Apr-88 1019 Common-Lisp-Object-System-mailer Recovery
C02845 00571 ∂02-May-88 0659 Common-Lisp-Object-System-mailer Re: symbol-class is bad name
C02848 00572 ∂02-May-88 0714 Common-Lisp-Object-System-mailer generic-function special form
C02852 00573 ∂02-May-88 0746 Common-Lisp-Object-System-mailer no-next-method lexical function
C02855 00574 ∂02-May-88 0746 Common-Lisp-Object-System-mailer no-next-method lexical function
C02858 00575 ∂02-May-88 0747 Common-Lisp-Object-System-mailer Re: type slot option
C02863 00576 ∂02-May-88 0850 Common-Lisp-Object-System-mailer Re: type slot option
C02866 00577 ∂02-May-88 0854 Common-Lisp-Object-System-mailer Re: documentation slot option
C02869 00578 ∂02-May-88 0903 Common-Lisp-Object-System-mailer Re: generic-function special form
C02872 00579 ∂02-May-88 0909 Common-Lisp-Object-System-mailer Re: no-next-method lexical function
C02875 00580 ∂02-May-88 0913 Common-Lisp-Object-System-mailer Re: symbol-class is bad name
C02877 00581 ∂03-May-88 1113 Common-Lisp-Object-System-mailer Re: no-next-method lexical function
C02880 00582 ∂03-May-88 1112 Common-Lisp-Object-System-mailer Re: symbol-class is bad name
C02883 00583 ∂03-May-88 1315 Common-Lisp-Object-System-mailer no-applicable-method
C02885 00584 ∂03-May-88 1454 Common-Lisp-Object-System-mailer Re: no-applicable-method
C02889 00585 ∂03-May-88 1536 Common-Lisp-Object-System-mailer Re: no-applicable-method
C02892 00586 ∂03-May-88 2125 Common-Lisp-Object-System-mailer Re: symbol-class is bad name
C02896 00587 ∂03-May-88 2337 Common-Lisp-Object-System-mailer symbol-class is bad name
C02900 00588 ∂04-May-88 0022 Common-Lisp-Object-System-mailer no-applicable-method
C02904 00589 ∂04-May-88 0850 Common-Lisp-Object-System-mailer Re: no-applicable-method
C02911 00590 ∂04-May-88 1053 Common-Lisp-Object-System-mailer no-next-method | no-applicable-method
C02919 00591 ∂04-May-88 1152 Common-Lisp-Object-System-mailer No-applicable-method
C02921 00592 ∂04-May-88 1257 Common-Lisp-Object-System-mailer Initialization
C02925 00593 ∂04-May-88 1355 Common-Lisp-Object-System-mailer Initialization
C02929 00594 ∂04-May-88 1419 Common-Lisp-Object-System-mailer Re: Sun Opposition To Chapter 3 Hereby Tendered
C02935 00595 ∂04-May-88 1621 Common-Lisp-Object-System-mailer Re: no-next-method | no-applicable-method
C02941 00596 ∂04-May-88 1721 Common-Lisp-Object-System-mailer Re: symbol-class is bad name
C02945 00597 ∂04-May-88 1836 Common-Lisp-Object-System-mailer Re: symbol-class is bad name
C02948 00598 ∂04-May-88 1855 Common-Lisp-Object-System-mailer Re: type slot option
C02954 00599 ∂04-May-88 1904 Common-Lisp-Object-System-mailer Re: generic-function special form
C02962 00600 ∂04-May-88 1932 Common-Lisp-Object-System-mailer Re: documentation slot option
C02966 00601 ∂04-May-88 1945 Common-Lisp-Object-System-mailer Re: No-applicable-method
C02968 00602 ∂04-May-88 2302 Common-Lisp-Object-System-mailer Initialization Names
C02969 00603 ∂05-May-88 0702 Common-Lisp-Object-System-mailer Initialization Names
C02971 00604 ∂05-May-88 1048 Common-Lisp-Object-System-mailer Initialization Names
C02974 00605 ∂05-May-88 1101 Common-Lisp-Object-System-mailer Re: Initialization Names
C02976 00606 ∂05-May-88 1111 Common-Lisp-Object-System-mailer Initialization-names
C02977 00607 ∂05-May-88 1556 Common-Lisp-Object-System-mailer Re: Initialization Names
C02979 00608 ∂05-May-88 1746 Common-Lisp-Object-System-mailer Re: type slot option
C02983 00609 ∂05-May-88 1741 Common-Lisp-Object-System-mailer Re: documentation slot option
C02986 00610 ∂05-May-88 1759 Common-Lisp-Object-System-mailer Re: symbol-class is bad name
C02990 00611 ∂05-May-88 1803 Common-Lisp-Object-System-mailer Re: Sun Opposition To Chapter 3 Hereby Tendered
C02992 00612 ∂05-May-88 1813 Common-Lisp-Object-System-mailer Re: generic-function special form
C02999 00613 ∂05-May-88 2005 Common-Lisp-Object-System-mailer Re: no-next-method | no-applicable-method
C03001 00614 ∂05-May-88 2005 Common-Lisp-Object-System-mailer "Written Responses" to CLOS 88-002: SETF Functions
C03007 00615 ∂05-May-88 2325 Common-Lisp-Object-System-mailer dealing with 1+2 comments
C03012 00616 ∂06-May-88 0933 Common-Lisp-Object-System-mailer Re: Sun Opposition To Chapter 3 Hereby Tendered
C03015 00617 ∂06-May-88 0950 Common-Lisp-Object-System-mailer Re: Reinitialization: check-initargs
C03023 00618 ∂06-May-88 1030 Common-Lisp-Object-System-mailer Re: Reinitialization: check-initargs
C03025 00619 ∂06-May-88 1033 Common-Lisp-Object-System-mailer Re: Sun Opposition To Chapter 3 Hereby Tendered
C03028 00620 ∂06-May-88 1033 Common-Lisp-Object-System-mailer Re: symbol-class is bad name
C03030 00621 ∂06-May-88 1336 Common-Lisp-Object-System-mailer Plan
C03037 00622 ∂06-May-88 1434 Common-Lisp-Object-System-mailer Re: Plan
C03039 00623 ∂06-May-88 1455 Common-Lisp-Object-System-mailer Plan Comments
C03041 00624 ∂06-May-88 2022 Common-Lisp-Object-System-mailer Plan Comments
C03044 00625 ∂06-May-88 2031 Common-Lisp-Object-System-mailer "Written Responses" to CLOS 88-002: SETF Functions
C03048 00626 ∂07-May-88 1106 Common-Lisp-Object-System-mailer Plan Comments
C03049 00627 ∂07-May-88 1111 RPG Question about discarded slots
C03053 00628 ∂09-May-88 0859 Common-Lisp-Object-System-mailer Plan Comments
C03056 00629 ∂09-May-88 1030 Common-Lisp-Object-System-mailer Plan Comments
C03058 00630 ∂09-May-88 1055 Common-Lisp-Object-System-mailer Re: Plan Comments
C03060 00631 ∂09-May-88 1115 Common-Lisp-Object-System-mailer (setf find-method)
C03061 00632 ∂09-May-88 1131 Common-Lisp-Object-System-mailer Re: Plan Comments
C03064 00633 ∂09-May-88 1135 Common-Lisp-Object-System-mailer (setf find-method)
C03067 00634 ∂09-May-88 1221 Common-Lisp-Object-System-mailer Re: Plan Comments
C03070 00635 ∂09-May-88 1221 Common-Lisp-Object-System-mailer Find-method
C03072 00636 ∂09-May-88 1329 Common-Lisp-Object-System-mailer Re: Find-method
C03074 00637 ∂09-May-88 1341 Common-Lisp-Object-System-mailer Re: Find-method
C03076 00638 ∂09-May-88 1520 Common-Lisp-Object-System-mailer Re: Plan Comments
C03079 00639 ∂09-May-88 1820 Common-Lisp-Object-System-mailer Re: Plan Comments
C03081 00640 ∂09-May-88 1822 Common-Lisp-Object-System-mailer Re: Plan Comments
C03084 00641 ∂09-May-88 2025 Common-Lisp-Object-System-mailer Plan Comments
C03086 00642 ∂10-May-88 1101 Common-Lisp-Object-System-mailer Re: Plan Comments
C03089 00643 ∂10-May-88 2141 Common-Lisp-Object-System-mailer check-keyword-arguments
C03094 00644 ∂11-May-88 1003 Common-Lisp-Object-System-mailer check-keyword-arguments
C03100 00645 ∂11-May-88 2047 Common-Lisp-Object-System-mailer :documentation
C03103 00646 ∂11-May-88 2114 Common-Lisp-Object-System-mailer Check-keyword-arguments
C03107 00647 ∂11-May-88 2119 Common-Lisp-Object-System-mailer Comments on MOP
C03112 00648 ∂12-May-88 0838 Common-Lisp-Object-System-mailer Check-keyword-arguments
C03117 00649 ∂12-May-88 0955 Common-Lisp-Object-System-mailer :documentation
C03119 00650 ∂12-May-88 1002 Common-Lisp-Object-System-mailer Re: :documentation
C03121 00651 ∂12-May-88 1234 Common-Lisp-Object-System-mailer :documentation
C03124 00652 ∂12-May-88 1315 Common-Lisp-Object-System-mailer Re: :documentation
C03128 00653 ∂12-May-88 1415 Common-Lisp-Object-System-mailer Re: Check-keyword-arguments
C03132 00654 ∂12-May-88 1415 Common-Lisp-Object-System-mailer Re: Check-keyword-arguments
C03136 00655 ∂12-May-88 1454 Common-Lisp-Object-System-mailer Re: :documentation
C03138 00656 ∂12-May-88 1605 Common-Lisp-Object-System-mailer Re: :documentation
C03141 00657 ∂12-May-88 1650 Common-Lisp-Object-System-mailer Re: :documentation
C03143 00658 ∂13-May-88 2103 Common-Lisp-Object-System-mailer Chapter 1
C03145 00659 ∂15-May-88 1054 Common-Lisp-Object-System-mailer Re: Check-keyword-arguments
C03148 00660 ∂15-May-88 1356 Common-Lisp-Object-System-mailer check-keyword-arguments
C03152 ENDMK
C⊗;
∂05-Oct-87 1028 Kahn.pa@Xerox.COM Re: no-applicable-method
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 5 Oct 87 10:28:10 PDT
Received: from Semillon.ms by ArpaGateway.ms ; 05 OCT 87 10:17:47 PDT
Date: Mon, 5 Oct 87 10:15:47 PDT
From: Ken Kahn <Kahn.pa@Xerox.COM>
Subject: Re: no-applicable-method
In-Reply-To: <871002-135007-6157@Xerox>
To: Danny Bobrow <Bobrow.pa@Xerox.COM>
cc: Moon@STONY-BROOK.SCRC.Symbolics.COM,
Common-Lisp-Object-System@SAIL.STANFORD.EDU
Message-ID: <871005-101747-1009@Xerox>
> Alternatively, no-applicable-method could search the argument list
for an
> element of the forwarder class to send the message to, else signal
an error.
> This would not make it so dependent on the first argument.
This discussion of forwarders implemented using no-applicable-method is
slipping between classical (first arg) forwarders and multi-method
forwarders. The classical case is pretty well-understood but doesn't
fit with CLOS (as responses to your first proposal pointed out). Here
you are proposing that forwarding happen on the first argument which is
an instance of forwarder class. What's special about the first one?
Forwarding should happen only when the object is actually involved (in
actor terminology -- receiving a message). The first argument which is
an instance of the forwarding class may passed around only to use under
extraordinary conditions (e.g. an error stream) or might be there to
embed in a structure (forwarding should not happen then).
Not only is it possible to start forwarding too soon, but one may miss
cases in which forwarding was intended. A generic function may have a
default method, or have methods that have T specifiers where the
forwarders are possible. no-applicable-method may never get called. An
elegant, but too expensive, solution is to define forwarders as classes
as not under T.
Forwarders are of limitted utility if they only work for generic
functions and not for ordinary functions. CLOS correctly hides that
distinction from callers. But I haven't heard anyone proposing that
ordinary functions call no-applicable-method when they get wrong-type
args.
Another worry I have about no-applicable-method is that it's piggy
backing upon what is essentially an error mechanism
(no-applicable-method). This seems to be a bad idea. (I remember a
lunch discussion during IJCAI-85 about forwarders and CommonLoops. Kent
Pitman argued well against forwarders using such a mechanism.
No-applicable-method may get called when forwarding is inappropriate
(e.g. buggy code).)
Finally, I think one has to be concerned with the efficiency of an
implementation of forwarding where arguments are consed together,
searched, spread out and several generic functions are called.
References
Bobrow's message of Fri, 2 Oct 87 13:50:00 PDT -- Re:
no-applicable-method
∂09-Oct-87 1428 Gregor.pa@Xerox.COM [goldman@vaxa.isi.edu: miscellaneous CLOS topics]
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 9 Oct 87 14:28:09 PDT
Received: from Semillon.ms by ArpaGateway.ms ; 09 OCT 87 14:26:37 PDT
Date: Fri, 9 Oct 87 14:26 PDT
From: Gregor.pa@Xerox.COM
Subject: [goldman@vaxa.isi.edu: miscellaneous CLOS topics]
To: Common-Lisp-Object-System@Sail.Stanford.edu
Message-ID: <871009142641.2.GREGOR@SPIFF.isl.parc.xerox.com>
Line-fold: no
Following are parts of a message I received with comments about CLOS.
Mostly, these comments address things we have already changed, but I
thought I would send them out anyways so they would be archived and also
so that we could have saved comments from a user about :accessor-prefix
and friends being confusing.
From: goldman@vaxa.isi.edu
Subject: miscellaneous CLOS topics
Date: Tue, 06 Oct 87 18:17:02 PDT
----------------------------------------------------------------
REDEFINING CLASSES
The way this section is worded makes it unclear to me what is supposed
to happen when I make multiple sequential changes to a DEFCLASS, creating
instances of each without accessing the "old" ones -- e.g.,
(DEFCLASS FOO ...)
create instance F1
(DEFCLASS FOO ...)
create instance F2
(DEFCLASS FOO ...)
now I access F1 and F2
Are there supposed to be copies of each obsolete FOO class around,
associated correcly with F1 and F2 so that the correct one is passed
to class-changed?
Also in this section, it states that CHANGE-CLASS preserves EQLness of
slot values for slots that are present in both the old and new class
definitions. Why EQLness, but not EQness?
----------------------------------------------------------------
"The initialization protocol of make-instance is not yet specified"
Is this still the case? I imagine everyone wants to be able to do
more with INITIALIZE-KEYWORDS-AND-VALUES than initialize slots, no?
----------------------------------------------------------------
DEFCLASS
:accessor-prefix, :reader-prefix
The syntax calls for a SYMBOL, but the semantics appears to really just
want a string, so a string should at LEAST be acceptable if not required.
BUT, saying that
"the names of the constructed functions are interned in the package that
is current at the time the defclass form is macro-expanded"
might make things easy on implementors, but it doesn't
do much for me as a poor application writer. As far as I can tell,
I don't have much to say about when an implementation really decides to
macroexpand something. I think there are (at least) two issues to
consider:
1) The decision here should be consistent with where DEFSTRUCT
interns the symbols for its accessors, copier, tester. CLtL is
suitably vague here, saying nothing under the description of :conc-name
and talking about the package at the time the defstruct is "processed"
in the other cases.
2) When I program in CommonLisp, I am used to being concerned about the
*package* setting at the time my source code is READ. So I would like to
feel assured that I can guarantee (preferably by natural means) what
package these symbols will end up in without having to EVEN CONSIDER the
question of the setting of *package* when some implementation chooses to
"process" or "macroexpand" these forms.
I would like to say that the new symbols must be interned in the
package that was current when the DEFCLASS form was read, but that of
course makes no sense. Another possibility is to
really require symbols, not strings, as the defclass syntax says,
and intern in the symbol-package of the prefix symbol, but that would
not work out well in cases where the prefix symbol turned out to be
visible by means of a USES or IMPORT, and not really be the same package
as READ was using. I would at the very least like to be able to
control the package in a simple way, say by permitting a more verbose
specification of the prefix options:
(:reader-prefix "foo-" :package "MYPKG")
I wish I had a really good idea for this, but I don't. I just feel uneasy
about having it defined in terms of MACROEXPAND time.
-------
∂09-Oct-87 1539 RPG Shared/class;local/instance
To: common-lisp-object-system@SAIL.Stanford.EDU
Danny and I agreed to the following terminological definition. If y'all
agree, we'll go with it:
1. We adopt the terms ``local'' and ``shared'' to describe the visibility
or scope of slots. The first, ``local,'' will refer to slots that are
visible to exactly one instance. The second, ``shared,'' will refer to
slots that are visible to a subset of the instances of a given class and
its subclasses. Often this subset is the same as the set of instances of
the class and its subclasses, but a smaller subset can result if a
subclass redefines the slot to be local to its instances.
2. We state that a slot with allocation type :instance is a local slot
and a slot with allocation type :class is a shared slot, and that
we leave room for extensions to CLOS in which other allocation types
are possible, but stipulate that only extensions that produce shared
or local slots are allowed.
3. We review all places where the terms ``shared'' and ``local'' are
currently used in the specification and decide whether what we are
saying at each place refers to shared/local slots or to slots whose
allocation types are :class/:instance. If the former, we leave the
wording essentially as it is; if the latter, we change the terminology
to use this wording or its equivalent: a slot with allocation type
:class (or :instance).
-rpg-
∂09-Oct-87 1618 Gregor.pa@Xerox.COM Shared/class;local/instance
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 9 Oct 87 16:18:24 PDT
Received: from Semillon.ms by ArpaGateway.ms ; 09 OCT 87 16:17:54 PDT
Date: Fri, 9 Oct 87 16:17 PDT
From: Gregor.pa@Xerox.COM
Subject: Shared/class;local/instance
To: Dick Gabriel <RPG@SAIL.Stanford.EDU>
cc: common-lisp-object-system@SAIL.Stanford.EDU
In-Reply-To: The message of 9 Oct 87 15:39 PDT from Dick Gabriel
<RPG@SAIL.Stanford.EDU>
Message-ID: <871009161758.8.GREGOR@SPIFF.isl.parc.xerox.com>
Line-fold: no
Date: 09 Oct 87 15:39 PDT
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>
Danny and I agreed to the following terminological definition. If y'all
agree, we'll go with it:
This all seems fine except...
2. We state that a slot with allocation type :instance is a local slot
and a slot with allocation type :class is a shared slot, and that
we leave room for extensions to CLOS in which other allocation types
are possible, but stipulate that only extensions that produce shared
or local slots are allowed.
I don't understand this. What does this restriction mean? Why?
-------
∂09-Oct-87 1610 Gregor.pa@Xerox.COM meeting at x3j13
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 9 Oct 87 16:10:25 PDT
Received: from Semillon.ms by ArpaGateway.ms ; 09 OCT 87 16:09:22 PDT
Date: Fri, 9 Oct 87 16:09 PDT
From: Gregor.pa@Xerox.COM
Subject: meeting at x3j13
To: Common-Lisp-Object-System@Sail.Stanford.edu
Message-ID: <871009160928.7.GREGOR@SPIFF.isl.parc.xerox.com>
Line-fold: no
Should we plan to get together the first day of the x3j13 meeting?
We should try to decide about this soon so we can make travel plans.
-------
∂09-Oct-87 1818 Moon@STONY-BROOK.SCRC.Symbolics.COM meeting at x3j13
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 9 Oct 87 18:18:10 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 252890; Fri 9-Oct-87 21:19:12 EDT
Date: Fri, 9 Oct 87 21:19 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: meeting at x3j13
To: Common-Lisp-Object-System@Sail.Stanford.edu
In-Reply-To: <871009160928.7.GREGOR@SPIFF.isl.parc.xerox.com>
Message-ID: <871009211908.5.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Fri, 9 Oct 87 16:09 PDT
From: Gregor.pa@Xerox.COM
Should we plan to get together the first day of the x3j13 meeting?
I had been assuming that we would.
∂09-Oct-87 1820 Moon@STONY-BROOK.SCRC.Symbolics.COM Shared/class;local/instance
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 9 Oct 87 18:19:54 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 252892; Fri 9-Oct-87 21:20:56 EDT
Date: Fri, 9 Oct 87 21:20 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Shared/class;local/instance
To: common-lisp-object-system@SAIL.Stanford.EDU
In-Reply-To: The message of 9 Oct 87 18:39 EDT from Dick Gabriel <RPG@SAIL.Stanford.EDU>
Message-ID: <871009212052.6.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: 09 Oct 87 1539 PDT
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>
Danny and I agreed to the following terminological definition.
No objections from this quarter.
∂10-Oct-87 1404 RPG Writing
To: common-lisp-object-system@SAIL.Stanford.EDU
Could each of you who believes s/he has sent us a final version
of something for the next draft please send me and Linda either
the dates and topics of such messages or the messages themselves once
more so that we can begin integration? Thanks.
-rpg-
∂11-Oct-87 2101 RPG Extent of CALL-NEXT-METHOD
To: common-lisp-object-system@SAIL.Stanford.EDU
Please vote for indefinite or dynamic.
-rpg-
∂12-Oct-87 0724 @RELAY.CS.NET:DUSSUD@jenner.csc.ti.com Re: Shared/class;local/instance
Received: from RELAY.CS.NET by SAIL.STANFORD.EDU with TCP; 12 Oct 87 07:24:11 PDT
Received: from relay2.cs.net by RELAY.CS.NET id ab08849; 12 Oct 87 10:00 EDT
Received: from csl.ti.com by RELAY.CS.NET id aa18349; 12 Oct 87 10:00 EDT
Received: from Jenner by tilde id AA07682; Mon, 12 Oct 87 07:32:30 CDT
Message-Id: <2770028852-5622498@Jenner>
Date: Mon, 12 Oct 87 07:27:32 CDT
From: Patrick H Dussud <DUSSUD@Jenner.csc.ti.com>
To: common-lisp-object-system@sail.stanford.edu
Subject: Re: Shared/class;local/instance
In-Reply-To: Msg of 09 Oct 87 1539 PDT from Dick Gabriel <RPG@sail.stanford.edu>
Danny and I agreed to the following terminological definition. If y'all
agree, we'll go with it:
OK.
Patrick.
∂12-Oct-87 0724 @RELAY.CS.NET:DUSSUD@jenner.csc.ti.com Re: meeting at x3j13
Received: from RELAY.CS.NET by SAIL.STANFORD.EDU with TCP; 12 Oct 87 07:24:21 PDT
Received: from relay2.cs.net by RELAY.CS.NET id ac08849; 12 Oct 87 10:00 EDT
Received: from csl.ti.com by RELAY.CS.NET id ab18349; 12 Oct 87 10:00 EDT
Received: from Jenner by tilde id AA07701; Mon, 12 Oct 87 07:33:37 CDT
Message-Id: <2770028924-5626820@Jenner>
Date: Mon, 12 Oct 87 07:28:44 CDT
From: Patrick H Dussud <DUSSUD@Jenner.csc.ti.com>
To: Common-Lisp-Object-System@sail.stanford.edu
Subject: Re: meeting at x3j13
In-Reply-To: Msg of Fri, 9 Oct 87 16:09 PDT from Gregor.pa@xerox.com
Should we plan to get together the first day of the x3j13 meeting?
Sounds good.
Patrick.
∂12-Oct-87 0724 @RELAY.CS.NET:DUSSUD@jenner.csc.ti.com Re: Extent of CALL-NEXT-METHOD
Received: from RELAY.CS.NET by SAIL.STANFORD.EDU with TCP; 12 Oct 87 07:24:47 PDT
Received: from relay2.cs.net by RELAY.CS.NET id ae08849; 12 Oct 87 10:01 EDT
Received: from csl.ti.com by RELAY.CS.NET id ac18349; 12 Oct 87 10:00 EDT
Received: from Jenner by tilde id AA07741; Mon, 12 Oct 87 07:36:04 CDT
Message-Id: <2770029069-5635569@Jenner>
Date: Mon, 12 Oct 87 07:31:09 CDT
From: Patrick H Dussud <DUSSUD@Jenner.csc.ti.com>
To: common-lisp-object-system@sail.stanford.edu
Subject: Re: Extent of CALL-NEXT-METHOD
In-Reply-To: Msg of 11 Oct 87 2101 PDT from Dick Gabriel <RPG@sail.stanford.edu>
Please vote for indefinite or dynamic.
I vote blank.
Patrick.
∂12-Oct-87 0851 Gregor.pa@Xerox.COM Extent of CALL-NEXT-METHOD
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 12 Oct 87 08:51:48 PDT
Received: from Semillon.ms by ArpaGateway.ms ; 12 OCT 87 08:52:24 PDT
Date: Mon, 12 Oct 87 08:52 PDT
From: Gregor.pa@Xerox.COM
Subject: Extent of CALL-NEXT-METHOD
To: Dick Gabriel <RPG@SAIL.Stanford.EDU>
cc: common-lisp-object-system@SAIL.Stanford.EDU
In-Reply-To: The message of 11 Oct 87 21:01 PDT from Dick Gabriel
<RPG@SAIL.Stanford.EDU>
Message-ID: <871012085217.4.GREGOR@SPIFF.isl.parc.xerox.com>
Line-fold: no
indefinite
-------
∂12-Oct-87 0913 Bobrow.pa@Xerox.COM Re: Extent of CALL-NEXT-METHOD
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 12 Oct 87 09:13:19 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 12 OCT 87 09:11:11 PDT
Date: 12 Oct 87 09:11 PDT
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Re: Extent of CALL-NEXT-METHOD
In-reply-to: Dick Gabriel <RPG@SAIL.Stanford.EDU>'s message of 11 Oct 87
21:01 PDT
To: RPG@SAIL.Stanford.EDU
cc: common-lisp-object-system@SAIL.Stanford.EDU
Message-ID: <871012-091111-3271@Xerox>
indefinite
danny
∂12-Oct-87 0918 Bobrow.pa@Xerox.COM Re: Extent of CALL-NEXT-METHOD
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 12 Oct 87 09:13:19 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 12 OCT 87 09:11:11 PDT
Date: 12 Oct 87 09:11 PDT
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Re: Extent of CALL-NEXT-METHOD
In-reply-to: Dick Gabriel <RPG@SAIL.Stanford.EDU>'s message of 11 Oct 87
21:01 PDT
To: RPG@SAIL.Stanford.EDU
cc: common-lisp-object-system@SAIL.Stanford.EDU
Message-ID: <871012-091111-3271@Xerox>
indefinite
danny
∂12-Oct-87 1102 Moon@STONY-BROOK.SCRC.Symbolics.COM Extent of CALL-NEXT-METHOD
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 12 Oct 87 09:43:04 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 253478; Mon 12-Oct-87 12:21:45 EDT
Date: Mon, 12 Oct 87 12:21 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Extent of CALL-NEXT-METHOD
To: common-lisp-object-system@SAIL.Stanford.EDU
In-Reply-To: The message of 12 Oct 87 00:01 EDT from Dick Gabriel <RPG@SAIL.Stanford.EDU>
Message-ID: <19871012162146.1.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: 11 Oct 87 2101 PDT
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>
Please vote for indefinite or dynamic [extent of CALL-NEXT-METHOD]
I really don't care what the standard says, but if you want me to
predict how Symbolics will implement it, I believe we will implement it
as indefinite extent. Certainly that is how we implement the
corresponding feature of whoppers now. (The extent is optimized to
dynamic if the compiler can prove that dynamic extent is adequate,
otherwise it remains indefinite.)
By the way, the closure captures the method objects, but not the method
functions; in other words, if you redefine a method, then call the
closure, the closure will call the new definition of the next method.
This is the same as the way we treat ordinary function calls in closures
(I don't believe CLtL actually prescribes what should happen in this
case. Should CLOS?)
∂12-Oct-87 1130 @Score.Stanford.EDU:kempf%hplabsz@hplabs.HP.COM Re: meeting at x3j13
Received: from SCORE.STANFORD.EDU by SAIL.STANFORD.EDU with TCP; 12 Oct 87 10:29:55 PDT
Received: from hplabs.HP.COM (hplabs.hpl.hp.com.#Internet) by SCORE.STANFORD.EDU with TCP; Mon 12 Oct 87 10:28:55-PDT
Received: from hplms2 by hplabs.HP.COM with SMTP ; Mon, 12 Oct 87 10:29:44 PDT
Received: from hplabsz.hpl.hp.com by hplms2; Mon, 12 Oct 87 13:29:30 edt
Return-Path: <kempf@hplabsz>
Received: from hplabsz by hplabsz; Mon, 12 Oct 87 11:30:36 pdt
To: Patrick H Dussud <DUSSUD@Jenner.csc.ti.com>
Cc: Common-Lisp-Object-System@sail.stanford.edu
Subject: Re: meeting at x3j13
X-Mailer: mh6.5
In-Reply-To: Your message of Mon, 12 Oct 87 07:28:44 -0500.
<2770028924-5626820@Jenner>
Date: Mon, 12 Oct 87 11:30:33 MDT
Message-Id: <14109.561058233@hplabsz>
From: kempf%hplabsz@hplabs.HP.COM
> Should we plan to get together the first day of the x3j13 meeting?
Yes.
jak
∂12-Oct-87 1131 @Score.Stanford.EDU:kempf%hplabsz@hplabs.HP.COM Re: Shared/class;local/instance
Received: from SCORE.STANFORD.EDU by SAIL.STANFORD.EDU with TCP; 12 Oct 87 10:43:43 PDT
Received: from hplabs.HP.COM (hplabs.hpl.hp.com.#Internet) by SCORE.STANFORD.EDU with TCP; Mon 12 Oct 87 10:43:12-PDT
Received: from hplms2 by hplabs.HP.COM with SMTP ; Mon, 12 Oct 87 10:44:01 PDT
Received: from hplabsz.hpl.hp.com by hplms2; Mon, 12 Oct 87 13:43:45 edt
Return-Path: <kempf@hplabsz>
Received: from hplabsz by hplabsz; Mon, 12 Oct 87 11:44:51 pdt
To: Dick Gabriel <RPG@SAIL.Stanford.EDU>
Cc: common-lisp-object-system@SAIL.Stanford.EDU
Subject: Re: Shared/class;local/instance
X-Mailer: mh6.5
In-Reply-To: Your message of 09 Oct 87 15:39:00 -0700.
Date: Mon, 12 Oct 87 11:44:48 MDT
Message-Id: <14295.561059088@hplabsz>
From: kempf%hplabsz@hplabs.HP.COM
Fine.
jak
∂12-Oct-87 1131 @Score.Stanford.EDU:kempf%hplabsz@hplabs.HP.COM Re: Extent of CALL-NEXT-METHOD
Received: from SCORE.STANFORD.EDU by SAIL.STANFORD.EDU with TCP; 12 Oct 87 10:43:05 PDT
Received: from hplabs.HP.COM (hplabs.hpl.hp.com.#Internet) by SCORE.STANFORD.EDU with TCP; Mon 12 Oct 87 10:42:34-PDT
Received: from hplms2 by hplabs.HP.COM with SMTP ; Mon, 12 Oct 87 10:43:13 PDT
Received: from hplabsz.hpl.hp.com by hplms2; Mon, 12 Oct 87 13:42:57 edt
Return-Path: <kempf@hplabsz>
Received: from hplabsz by hplabsz; Mon, 12 Oct 87 11:42:52 pdt
To: Dick Gabriel <RPG@SAIL.Stanford.EDU>
Cc: common-lisp-object-system@SAIL.Stanford.EDU
Subject: Re: Extent of CALL-NEXT-METHOD
X-Mailer: mh6.5
In-Reply-To: Your message of 11 Oct 87 21:01:00 -0700.
Date: Mon, 12 Oct 87 11:42:49 MDT
Message-Id: <14272.561058969@hplabsz>
From: kempf%hplabsz@hplabs.HP.COM
dynamic
jak
∂12-Oct-87 1145 MASINTER.PA@Xerox.COM extent of CALL-NEXT-METHOD
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 12 Oct 87 11:45:17 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 12 OCT 87 11:45:54 PDT
From: MASINTER.PA@Xerox.COM
Date: 12 Oct 87 11:42:48 PDT
Subject: extent of CALL-NEXT-METHOD
To: common-lisp-object-system@Sail.Stanford.Edu
Message-ID: <871012-114554-3632@Xerox>
Dynamic.
∂12-Oct-87 1348 Gregor.pa@Xerox.COM Extent of CALL-NEXT-METHOD
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 12 Oct 87 13:48:18 PDT
Received: from Semillon.ms by ArpaGateway.ms ; 12 OCT 87 13:29:16 PDT
Date: Mon, 12 Oct 87 13:29 PDT
From: Gregor.pa@Xerox.COM
Subject: Extent of CALL-NEXT-METHOD
To: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
cc: common-lisp-object-system@SAIL.Stanford.EDU
In-Reply-To: <19871012162146.1.MOON@EUPHRATES.SCRC.Symbolics.COM>
Message-ID: <871012132910.0.GREGOR@SPIFF.isl.parc.xerox.com>
Line-fold: no
Date: Mon, 12 Oct 87 12:21 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
By the way, the closure captures the method objects, but not the method
functions; in other words, if you redefine a method, then call the
closure, the closure will call the new definition of the next method.
This is the same as the way we treat ordinary function calls in closures
(I don't believe CLtL actually prescribes what should happen in this
case. Should CLOS?)
It seems to me that this has to do with whether defmethod (and friends)
replace the existing method or alter the existing method. I thought
defmethod replaced the existing method; so it seems to me that if the
closure captures the method objects redefining one of the captured
methods should have no effect on the closure.
-------
∂12-Oct-87 1351 Moon@STONY-BROOK.SCRC.Symbolics.COM fixing our problems with setf
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 12 Oct 87 13:51:21 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 253615; Mon 12-Oct-87 16:52:14 EDT
Date: Mon, 12 Oct 87 16:52 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: fixing our problems with setf
To: Common-Lisp-Object-System@SAIL.STANFORD.EDU
In-Reply-To: <870928165521.9.MOON@EUPHRATES.SCRC.Symbolics.COM>,
<871002163721.4.GREGOR@SPIFF.isl.parc.xerox.com>
Message-ID: <19871012205211.7.MOON@EUPHRATES.SCRC.Symbolics.COM>
After thinking it over, I think Gregor's proposal to simplify the
way setf-functions work is reasonable. There will be some adoption
cost for us, because the order of arguments to a setf function is
being changed from what we agreed on before, but I think we can
come up with a compatibility kludge to take care of that. Of course,
Gregor's proposal doesn't really eliminate the scoping issues, not
only because we cannot get rid of defsetf and define-setf-method,
but also because of the already defined interaction of setf with
macros. However, I think the scoping rules are quite straightforward.
Here is a revised version of what I mailed out on September 28,
modified and simplified to reflect what Gregor proposed:
The goal is to unify the handling of "setf functions" with the handling
of regular functions, so we don't need a proliferation of -setf versions
of defmethod, defgeneric, ensure-generic-function, fboundp, generic-labels,
with-added-methods, etc. The major issue is that Common Lisp has not seen
a need to do this already, so the onus falls on CLOS. In addition, we
ran into difficulty with confusion between the idea of associating a
function name with a function object (in our case, a generic function
object), and the idea of associating a way to setf a function with that
function. This proposal clarifies the situation.
Add to Common Lisp the same concept of "setf functions" that we are
already introducing in CLOS. Right now, Common Lisp only has "setf
macros", which are defined by define-setf-method and both forms of
defsetf. I draw the distinction because a "setf macro" is something
that produces code (or other specifications, as in define-setf-method)
which, when evaluated, will perform the effect of an invocation of setf,
while a "setf function" is something that is called to perform directly
the effect of an invocation of setf.
As with regular functions, associated with any given name you can have a
setf function or a setf macro, but not both. This means that one does
not define a setf function (with defmethod or defgeneric) and also call
defsetf. The mere act of defining the setf function is enough to tell
setf what to do. In fact setf only needs for the setf function to be
defined at run time, not at compile time.
Since setf functions are in a separate, but parallel, namespace from
regular functions, we need a way to name them. The simplest way is to
allow a list (setf -name-) to be used as the name of the setf function
that is called to perform the effect of (setf (-name- ...) ...). The
following functions, macros, and special forms defined in CLtL need to
be enhanced to accept such lists where they now accept symbols as
function names:
compile
defun
disassemble
documentation
fboundp
flet
fmakunbound
function
labels
symbol-function and setf of symbol-function
trace
untrace
and the declarations ftype, function, inline, and notinline
This makes the name of symbol-function a bit obsolete, but I do not
propose to introduce a new function to replace it. The discrepancy is
not that important.
The following functions, macros, and special forms defined in CLOS need
to be enhanced in the same way:
defgeneric
defmethod
ensure-generic-function
generic-flet
generic-labels
with-added-methods
defmethod-setf and defgeneric-setf need to be removed.
Note that in Common Lisp, setf macroexpansion is an operation on
function names, not on functions. It differs from some dialects of
Scheme, such as T, in this respect. This proposal does not attempt to
change that.
Note that I do not propose to introduce lexically local setf macros,
that is, a cross between defsetf and macrolet. This does not appear to
be logically necessary. If someone else wants this, it would certainly
not be hard to do. The main issue is whether all three ways of defining
lexically global setf macros need local counterparts. A secondary issue
is whether to define the meaning of defmacro or macrolet of (setf foo).
I also do not now propose to clarify the definition of global setf
macros, for example to say that (macro-function '(setf foo)) returns an
expander function that takes two arguments and returns five values.
These issues logically belong to Common Lisp, not to CLOS.
Contrary to what we already decided about the lambda-list of a
setf-function, the new value to be stored will be passed as the first
argument. Thus, #'(setf foo) takes one more required argument than
#'foo, the first required argument is the new value to be stored, and
the remaining arguments are the same as #'foo's arguments.
The function-defining macros defun, flet, labels, defgeneric, defmethod,
and the :method option to defgeneric, generic-flet, generic-labels, and
with-added-methods will not have a special syntax with two lambda-lists
when defining a setf function, contrary to what we decided before. The
programmer writing a setf-function must know to insert the new-value
parameter at the front of the lambda-list.
The remaining issue is a scoping issue. We have introduced lexically
local setf functions, where before Common Lisp only had lexically global
setf macros. Thus the namespace of setf operators has been extended to
have a lexical component, just like the namespace of regular operators.
(Recall that "operator" means the union of functions, macros, and
special forms). Regular functions and setf functions naturally come in
pairs, but since they are defined separately we have to specify what
happens in various cases where only one is defined at a given lexical
contour. The following rules for the behavior of SETF suffice; note
that these rules are ordered and the first rule to apply supersedes any
later rules. These rules are a consistent extension of the current
behavior of Common Lisp and the Cleanup committee's resolution of issue
GET-SETF-METHOD-ENVIRONMENT.
Rules for the macroexpansion of (setf (foo x) y):
(1) If the function-name foo refers to the global function definition,
rather than a locally defined function or macro, and if there is a
setf-macro defined for foo, use the setf-macro to compute the expansion.
(2) If the function-name foo is defined as a macro in the current scope,
use macroexpand-1 to expand (foo x) and try again.
(3) If the function-name foo is defined as a special form in the current
scope, signal an error.
(4) Expand into the equivalent of
(let ((#:temp-1 x)
(#:temp-2 y))
(funcall #'(setf foo) #:temp-2 #:temp-1))
Note that rule 4 is independent of the scope of the function name
(setf foo) and does not care if that scope is different from the scope
of the function name foo. This allows some nonsensical programs to
be written, but does not seem harmful enough to justify making the
rules more complicated.
Example (for Patrick):
(defmethod (setf subseq)
((new-value vector) (sequence vector) start &optional end)
(unless end (setq end (length sequence)))
(setq end (min end (+ start (length new-value))))
(do ((i start (1+ i))
(j 0 (1+ j)))
((= i end) new-value)
(setf (aref sequence i) (aref new-value j))))
If this meets with general approval I will recast this for the Cleanup
committee.
∂12-Oct-87 1357 Moon@STONY-BROOK.SCRC.Symbolics.COM Extent of CALL-NEXT-METHOD
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 12 Oct 87 13:57:46 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 253620; Mon 12-Oct-87 16:58:47 EDT
Date: Mon, 12 Oct 87 16:58 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Extent of CALL-NEXT-METHOD
To: common-lisp-object-system@SAIL.Stanford.EDU
In-Reply-To: <871012132910.0.GREGOR@SPIFF.isl.parc.xerox.com>
Message-ID: <19871012205849.8.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Mon, 12 Oct 87 13:29 PDT
From: Gregor.pa@Xerox.COM
It seems to me that this has to do with whether defmethod (and friends)
replace the existing method or alter the existing method. I thought
defmethod replaced the existing method; so it seems to me that if the
closure captures the method objects redefining one of the captured
methods should have no effect on the closure.
defmethod should behave consistently with defclass and defgeneric in
this respect. The latter two alter an existing object rather than
creating a new object.
∂12-Oct-87 1553 @RELAY.CS.NET:DUSSUD@jenner.csc.ti.com Re: Constructors
Received: from RELAY.CS.NET by SAIL.STANFORD.EDU with TCP; 12 Oct 87 15:53:25 PDT
Received: by RELAY.CS.NET id aa14355; 12 Oct 87 18:06 EDT
Received: from relay2.cs.net by RELAY.CS.NET id ah13934; 12 Oct 87 17:37 EDT
Received: from csl.ti.com by RELAY.CS.NET id ag20424; 12 Oct 87 17:33 EDT
Received: from dsg by tilde id AA19217; Mon, 12 Oct 87 15:10:57 CDT
Received: From Jenner By dsg Via CHAOS-NET With CHAOS-MAIL; Mon, 12 Oct 87 14:15:21 CDT
Message-Id: <2770052978-7072022@Jenner>
Date: Mon, 12 Oct 87 14:09:38 CDT
From: Patrick H Dussud <DUSSUD@Jenner.csc.ti.com>
To: Common-Lisp-Object-System@SAIL.STANFORD.EDU
Subject: Re: Constructors
In-Reply-To: Msg of Wed, 30 Sep 87 12:37 EDT from "David A. Moon"<Moon@scrc-stony-brook.arpa>
In-Reply-To: Msg of Sat, 3 Oct 87 12:59 PDT from Gregor.pa@XEROX.COM
In-Reply-To: Msg of Sat, 3 Oct 87 13:26 PDT from Gregor.pa@XEROX.COM
[From Gregor]
I am still opposed to adding constructors to CLOS. I do believe that
they will make life a little more convenient for some programmers, but I
don't think those advantages outweigh the conceptual problems I outline
above nor do I think they are worth the added complexity of having to
describe and understand how they work and documenting the mechanism
which is used to compile them and cause them to get recompiled when
appropriate.
I don't believe that the programmer's interface (:CONSTRUCTOR option) is
complicated, the rules are like DEFSTRUCT ones.
The meta level is where all the conceptual complexity goes. But
power and reusability are more important than simplicity at this level.
Some people may object about the added code size, but any non trivial
implementation will have to optimize instance creation one way or
another.
As for the discussion about having to edit the constructor option when
the classes are redefined because some initargs would have been changed,
I think that goes in favor of the constructor options, the definition of
the interface is lexically close to where the default initargs are. If
you have a defun form for the constructor, you will have to edit the
defclass form (to edit the default initargs) and the defun form.
I don't think that we should say that constructors are going to be
faster than make-instance but the truth is that they are likely to be on
lots of implementations.
In conclusion since I don't think the option is hard to understand or to
explain and since any serious implementation will have to do something
like that (at the sub-meta level at least), I think it is a good thing
to standardize.
Patrick.
∂12-Oct-87 1615 @RELAY.CS.NET:DUSSUD@jenner.csc.ti.com
Received: from RELAY.CS.NET by SAIL.STANFORD.EDU with TCP; 12 Oct 87 16:15:36 PDT
Received: by RELAY.CS.NET id ab14606; 12 Oct 87 18:26 EDT
Received: from relay2.cs.net by RELAY.CS.NET id ai13934; 12 Oct 87 17:37 EDT
Received: from csl.ti.com by RELAY.CS.NET id ah20424; 12 Oct 87 17:33 EDT
Received: from dsg by tilde id AA19227; Mon, 12 Oct 87 15:11:07 CDT
Received: From Jenner By dsg Via CHAOS-NET With CHAOS-MAIL; Mon, 12 Oct 87 14:46:46 CDT
Message-Id: <2770054846-7184236@Jenner>
Date: Mon, 12 Oct 87 14:40:46 CDT
From: Patrick H Dussud <DUSSUD@Jenner.csc.ti.com>
To: Danny Bobrow <Bobrow.pa@xerox.com>
Cc: Common-Lisp-Object-System@sail.stanford.edu
Subject: Re: Should redefining a class reinitialize shared slots?
In-Reply-To: Msg of 30 Sep 87 17:30 PDT from Danny Bobrow <Bobrow.pa@xerox.com>
It seems to me the only predictable rules are: (1) all
class slots retain their values when the class is redefined. (2)
all class slots are reinitialized when the class is redefined.
I prefer rule 1 because it is analogous to the rule for
instance slots. Also, it's easier to reinitialize a slot that was
retained than to retain a slot that was reinitialized, if a user
wants to implement behavior different from the default.
I find these arguments strong, but still find rule 2 is most consistent.
Rule 1 probably is desirable in most cases, but I think will be
confusing when we consider the above cases -- again, shades of DWIM. My
intuition is not strong on this, so I would like to see opinions from
Gregor and Patrick (others too, of course).
If we think of those slots as shared instead of class slots, then the
issue of consistency of behavior with local slots becomes more important.
They shouldn't be reinitialized when the class gets redefined.
Patrick.
∂12-Oct-87 1727 @RELAY.CS.NET:DUSSUD@jenner.csc.ti.com Re: fixing our problems with setf
Received: from RELAY.CS.NET by SAIL.STANFORD.EDU with TCP; 12 Oct 87 17:27:36 PDT
Received: from relay2.cs.net by RELAY.CS.NET id aa13933; 12 Oct 87 17:36 EDT
Received: from csl.ti.com by RELAY.CS.NET id aa20424; 12 Oct 87 17:30 EDT
Received: from dsg by tilde id AA19076; Mon, 12 Oct 87 15:07:36 CDT
Received: From Jenner By dsg Via CHAOS-NET With CHAOS-MAIL; Mon, 12 Oct 87 12:11:51 CDT
Message-Id: <2770045473-6621103@Jenner>
Date: Mon, 12 Oct 87 12:04:33 CDT
From: Patrick H Dussud <DUSSUD@Jenner.csc.ti.com>
To: Common-Lisp-Object-System@sail.stanford.edu
Subject: Re: fixing our problems with setf
In-Reply-To: Msg of Fri, 2 Oct 87 16:37 PDT from Gregor.pa@xerox.com
Also because the expansion of setf does not depend on the argument
list of FOO or (SETF FOO), there can't be any problems with having to
re-expand (recompile) code after the defun for foo or (setf foo)
changes. This rule for setf always puts the new value argument as the
first of the other arguments, this rule always works since it doesn't
depend on the definition of FOO or (SETF FOO).
The point I see in favor of having the new value after all the required
is it suggests that it will be the least significant argument for method
selection. Putting new value first suggests that it will be the most
significant (which is generally not what you want). Besides this
point, the idea of having the combined setf lambda list independent of
the original lambda list is attractive.
The remaining issue is a scoping issue. We have introduced lexically
local setf functions, where before Common Lisp only had lexically global
setf macros. Thus the namespace of setf operators has been extended to
have a lexical component, just like the namespace of regular operators.
(Recall that "operator" means the union of functions, macros, and
special forms). Regular functions and setf functions naturally come in
pairs, but since they are defined separately we have to specify what
happens in various cases where only one is defined at a given lexical
contour.
Scoping is not a problem in my proposal provided the programmer never
uses defsetf. Because setf always expands the same way, all the
programmer needs to do is provide lexical definitions for the actual
setf function (SETF FOO).
-------
I will be unrealistic to consider that programmers won't use DEFSETF.
All of what Moon included under this issue is still valid.
Patrick.
∂12-Oct-87 1729 @RELAY.CS.NET:DUSSUD@jenner.csc.ti.com Re: Shared/class;local/instance
Received: from RELAY.CS.NET by SAIL.STANFORD.EDU with TCP; 12 Oct 87 17:29:39 PDT
Received: from relay2.cs.net by RELAY.CS.NET id ad13933; 12 Oct 87 17:37 EDT
Received: from csl.ti.com by RELAY.CS.NET id ai20424; 12 Oct 87 17:33 EDT
Received: from dsg by tilde id AA19231; Mon, 12 Oct 87 15:11:13 CDT
Received: From Jenner By dsg Via CHAOS-NET With CHAOS-MAIL; Mon, 12 Oct 87 15:03:07 CDT
Message-Id: <2770055843-7244188@Jenner>
Date: Mon, 12 Oct 87 14:57:23 CDT
From: Patrick H Dussud <DUSSUD@Jenner.csc.ti.com>
To: common-lisp-object-system@sail.stanford.edu
Subject: Re: Shared/class;local/instance
In-Reply-To: Msg of 09 Oct 87 1539 PDT from Dick Gabriel <RPG@sail.stanford.edu>
Danny and I agreed to the following terminological definition. If y'all
agree, we'll go with it:
1. We adopt the terms ``local'' and ``shared'' to describe the visibility
or scope of slots. The first, ``local,'' will refer to slots that are
visible to exactly one instance. The second, ``shared,'' will refer to
slots that are visible to a subset of the instances of a given class and
its subclasses. Often this subset is the same as the set of instances of
the class and its subclasses, but a smaller subset can result if a
subclass redefines the slot to be local to its instances.
↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
I don't think this paragraph is correct if you don't delete the marked
words. Redefining a slot as a shared slot in a subclass S of a class C
affect the visibility of this slots as well. the new slot (seen by the
instances of S) will not be shared with those of C.
Patrick.
∂12-Oct-87 1737 RPG shared/class;local/instance
To: common-lisp-object-system@SAIL.Stanford.EDU
subclass redefines the slot to be local to its instances.
↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
Right. I already had deleted it in chapter 1.
-rpg-
∂12-Oct-87 1743 Bobrow.pa@Xerox.COM Re: Shared/class;local/instance
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 12 Oct 87 17:43:50 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 12 OCT 87 17:43:10 PDT
Date: 12 Oct 87 17:43 PDT
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Re: Shared/class;local/instance
In-reply-to: Patrick H Dussud <DUSSUD@Jenner.csc.ti.com>'s message of
Mon, 12 Oct 87 14:57:23 CDT
To: DUSSUD@Jenner.csc.ti.com
cc: common-lisp-object-system@sail.stanford.edu
Message-ID: <871012-174310-4257@Xerox>
Often this subset is the same as the set of instances of
the class and its subclasses, but a smaller subset can result if a
subclass redefines the slot to be local to its instances.
↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
I don't think this paragraph is correct if you don't delete the
marked words.
Right.
∂12-Oct-87 1803 Moon@STONY-BROOK.SCRC.Symbolics.COM Object Creation Writeup
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 12 Oct 87 18:02:44 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 253739; Mon 12-Oct-87 21:03:43 EDT
Date: Mon, 12 Oct 87 21:03 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Object Creation Writeup
To: Common-Lisp-Object-System@sail.stanford.edu
Message-ID: <19871013010341.1.MOON@EUPHRATES.SCRC.Symbolics.COM>
Dick, this is the final draft of the Object Creation Writeup, unless
we send you any corrections on Tuesday.
-foo- means the word foo in italics. FOO means the word foo in boldface.
>>>> New Writing
Page 1-5 Creating Instances of Classes
[Replace existing text with this. The goal is to give an overview of
creating instances. It's too early to discuss initialization in detail
because we haven't discussed methods yet.]
The generic function MAKE-INSTANCE creates and returns a new instance of
a class. CLOS provides a flexible means for specifying how a new
instance is initialized. For example, users specify how to fill the
slots with values (either by giving an argument to MAKE-INSTANCE, or by
providing a default initial value). Users can also write methods that
perform extra initialization. The complete initialization protocol is
described in the section "Object Creation and Initialization".
Page 1-27: New Chapter: Object Creation and Initialization
SECTION: Overview
The function MAKE-INSTANCE creates and returns a new instance of a
class. The first argument is a class or the name of a class, and the
remaining arguments are an initarg ("initialization argument") list.
Initialization consists of several distinct steps, including: combining
the explicitly supplied initargs with the default values for the
unsupplied initargs, checking the validity of the initargs, allocating
storage for the instance, filling slots with values, and executing
user-supplied methods that perform additional initialization. CLOS
defines MAKE-INSTANCE in a procedural way, with each step represented by
a generic function. This gives the user the ability to customize any
number of the steps. In addition, MAKE-INSTANCE is a generic function,
allowing the user to replace the entire procedure if so inclined.
CLOS specifies default methods for each step, so there is a well-defined
standard behavior for the entire initialization procedure. For many
programs, the standard behavior is appropriate. The standard behavior
provides users with four simple mechanisms for controlling
initialization:
- Declaring a symbol to be an initarg for a slot, by
by using the :INITARG slot option. This allows one to
provide a value for a slot in a call to MAKE-INSTANCE.
- Supplying a default value form for an initarg, by using the
:DEFAULT-INITARGS class option. This default value is used if the
initarg is not explicitly provided as an argument to MAKE-INSTANCE.
- Supplying a default value form for a slot, by using the :INITFORM
slot option. This default value is stored into the slot if no
initarg associated with that slot is given as an argument to
MAKE-INSTANCE or defaulted by :DEFAULT-INITARGS.
- Defining methods for INITIALIZE-INSTANCE. The slot-filling
behavior described above is implemented by a system-supplied
default method for INITIALIZE-INSTANCE. When users need
to exert greater control over initialization, they can provide
methods for INITIALIZE-INSTANCE. In most cases :AFTER methods
are appropriate for this purpose, because they are called
after the default method that fills the slots, and thus do not
override the normal slot-filling behavior.
Note that the object creation and initialization procedure can be
controlled at two different levels. The standard behavior offers the
four mechanisms mentioned above; this level can be considered the
Programmer Interface level. At the Meta-object level, users can exert
greater control over each step of this procedure; this level can be
considered the interface for experimentation with alternative
object-oriented paradigms.
There is one general guideline that distinguishes between the Programmer
Interface level and the Meta-object levels of programming. To customize
behavior at the Programmer Interface level, the user defines methods
that specialize on instances. That is, the arguments that select
methods are instances. To customize behavior at the Meta-object level,
the user defines methods that specialize on classes. That is, the
arguments that select methods are classes.
This chapter begins by describing the terminology and concepts of the
standard initialization behavior, which is the Programmer Interface.
This chapter then describes the procedural definition of MAKE-INSTANCE.
It briefly mentions the generic functions that implement each step of
the procedure; this is the Meta-object level of initialiation. The
details of these functions are documented in Chapter 3.
SECTION: Terminology Related to Object Creation and Initialization
The terminology related to object creation and initialization is
presented here:
-initarg-. An initarg (initialization argument) is a keyword argument
that can be used to control object creation and initialization. The
&key arguments to MAKE-INSTANCE are initargs. It is often convenient to
use keyword symbols to name initargs, but the name of an initarg can be
any symbol, including NIL. There are two possible purposes for an
initarg: to fill a slot with a value or to provide an argument for
an initialization method. A single initarg can be used for more than
one purpose.
-initarg list-. An initarg list (initialization argument list) is a
list of alternating initarg names and values. Its structure is
identical to a property list and also identical to the portion of an
argument list processed for &key parameters. As in those lists, if an
initarg name appears more than once in an initarg list, the leftmost
occurrence supplies the value and the remaining occurrences are ignored.
The arguments to MAKE-INSTANCE (after the first argument) are an initarg
list. As in an &key argument list, :ALLOW-OTHER-KEYS can appear in an
initarg list, and if its value is non-NIL, error-checking of initarg
names is disabled.
-slot-filling initarg-. An initarg associated with a slot. If
the initarg has a value in the initarg list, the value is stored into
the slot of the newly-created object, overriding any initform associated
with the slot. A single initarg can fill more than one slot. A
slot-filling initarg that fills a shared slot stores its value into the
shared slot, replacing any previous value.
-method-implemented initarg-. An initarg associated with a method. A
method-implemented initarg is intended as an argument for one or more
methods for INITIALIZE-INSTANCE or ALLOCATE-INSTANCE. When an object is
created, the method is called with the initarg's value as an argument
and the method uses the value however it chooses. If the initarg has no
value in the initarg list, the method's lambda-list supplies a default
value.
SECTION: Declaring the Validity of Initargs
MAKE-INSTANCE checks the validity of the initargs and signals an error
if an initarg is supplied that is not valid. An initarg is declared
as valid in the same place where its purpose (whether slot-filling or
method-implemented) is stated.
Slot-filling initargs are declared as valid by the :INITARG slot option
to DEFCLASS. The :INITARG slot option is inherited from superclasses.
Thus, the set of valid slot-filling initargs for a class is the union of
the initargs declared by the class and its superclasses.
Method-implemented initargs are declared as valid by defining methods
for INITIALIZE-INSTANCE or ALLOCATE-INSTANCE. The keyword name of each
keyword parameter specifier in the method's lambda-list becomes a
method-implemented initarg for all classes for which this method is
applicable. Thus, method inheritance controls the set of valid
method-implemented initargs.
The set of valid initargs for a class is the union of the valid
slot-filling initargs, the valid method-implemented initargs, and the
pre-defined initarg :ALLOW-OTHER-KEYS. The default for
:ALLOW-OTHER-KEYS is NIL, and its specification is the same as Common
Lisp defines for &KEY argument lists.
SECTION: Defaulting of Initargs
A -default value form- can be supplied for an initarg. The way to
provide a default value form for either a slot-filling and
method-implemented initarg is to use the :DEFAULT-INITARGS class option.
A default value form is usually specified by a different class from the
class that declared the initarg as valid. Thus, :DEFAULT-INITARGS is
usually used to supply a default value for an inherited initarg.
The :DEFAULT-INITARGS class option is inherited. See ``Inheritance of
Class Options''.
The :DEFAULT-INITARGS class option is followed by alternating initarg
names and forms. Each form is the default value form for the
corresponding initarg. The default value form of an initarg is used
only if that initarg does not appear in the arguments to MAKE-INSTANCE.
In that case, the default value form is evaluated in the lexical
environment of the DEFCLASS form that supplied it, and the resulting
value is used as the initarg's value. The initarg name and value are
appended to the initarg list supplied to MAKE-INSTANCE. The result is
a -defaulted initarg list- in which the explicitly supplied initargs
appear before the defaulted initargs. Defaulted initargs are ordered
according to the order in the class precedence list of the classes
that supplied the default values.
The :DEFAULT-INITARGS option is used only to provide default values for
initargs; it does not declare a symbol as a valid initarg name.
One should distinguish between the purposes of :DEFAULT-INITARGS and
:INITFORM, with respect to slot-filling initargs. The
:DEFAULT-INITARGS class option allows the user to give a default value
form for an initarg without knowing whether or not the initarg fills a
slot. If that initarg is not explicitly supplied in a call to
MAKE-INSTANCE, the default value form is used, just as if it had been
supplied in the call. In contrast, the :INITFORM slot option allows
the user to give a default initial value form for a slot. An :INITFORM
is used only if no initarg associated with that slot is given as an
argument to MAKE-INSTANCE or defaulted by :DEFAULT-INITARGS. The two
kinds of defaulting exist at different levels of abstraction.
Note: CLOS does not guarantee any given order of evaluation of
default-initarg forms and initforms. If there are dependencies among
these forms, INITIALIZE-INSTANCE methods should be used instead. In
most programs, the initforms and default-initarg forms are either
constants or simple forms that construct new objects; forms with
side-effects are permitted, but are not typically used.
SECTION: Rules for Duplication of Initargs
The following rules specify what happens when initargs are duplicated in
various ways.
- The :INITARG slot option may be specified more than once for a given slot.
- A single initarg can initialize more than one slot if the same initarg name
appears in more than one :INITARG slot option.
- It is valid for a given initarg name to be defined more than once as a
slot-filling initarg, as a method-implemented initarg, or both.
- If two initargs that initialize the same slot, with the same or different
names, are given in the arguments to MAKE-INSTANCE, the leftmost of these
initargs in the initarg list prevails. This behavior is consistent
with the behavior of property lists and the portion of an argument
list processed for &key parameters.
- If two different initargs that initialize the same slot have default values,
and neither is given explicitly in the arguments to MAKE-INSTANCE,
the initarg that appears in a :DEFAULT-INITARGS slot option in the most
specific class prevails, or if they appeared in the same class, the one whose
mention in :DEFAULT-INITARGS is leftmost in the DEFCLASS form prevails.
During the defaulting of initargs, the defaults are appended
to the end of the initarg list in this order.
- If there are two different initargs that initialize the same slot, and one
was given explicitly in the arguments to MAKE-INSTANCE while the other was
defaulted via :DEFAULT-INITARGS, the explicit one prevails. (This rule is
implied by the two preceding rules, but it is worth mentioning
explicitly.)
- If a slot has both an :INITFORM and an :INITARG slot option, and the
slot-filling initarg is defaulted via :DEFAULT-INITARGS, the initform is not
used and is not evaluated.
An illustrative example of the above rules:
(defclass a () ((x :initarg a)))
(defclass b (a) ((x :initarg b))
(:default-initargs a 1 b 2))
DEFAULTED
FORM INITARG LIST CONTENTS OF X SLOT
(make-instance 'b) (a 1 b 2) 1
(make-instance 'b 'a 3) (a 3 b 2) 3
(make-instance 'b 'b 4) (b 4 a 1) 4
(make-instance 'b 'a 1 'a 2) (a 1 a 2 b 2) 1
SECTION: Methods for INITIALIZE-INSTANCE
INITIALIZE-INSTANCE is a generic function that uses standard method
combination. Users can define methods for INITIALIZE-INSTANCE to
perform any initialization that cannot be achieved with the simple
slot-filling mechanisms.
CLOS calls the generic function INITIALIZE-INSTANCE after it has:
- Computed the defaulted initarg list by combining the
supplied initarg list with any default initargs
for the class.
- Checked the validity of the defaulted initarg list. If any
of the initargs has not been declared as valid, an error is
signaled.
- Created a blank instance.
CLOS then calls INITIALIZE-INSTANCE with the blank instance and the
defaulted initarg list. The system-supplied default method is a
primary method that initializes the slots with values according to the
initarg list. For each slot (whether local or shared):
- If an initarg in the defaulted initarg list fills that slot, its
value is stored into the slot. (This is true even if a :BEFORE method
has modified the slot.)
- Otherwise, if the slot is uninitialized and it has an initform, the
initform is evaluated and the result is stored into the slot.
- The duplicate-resolution rules mentioned in the section "Rules for
Duplication of Initargs" are obeyed.
Typically, user-defined methods are :AFTER methods; however that is not
a requirement. Users should take care not to supply primary methods
that override the default primary method unless they want to prevent
the normal slot-filling from occurring.
CLOS provides two functions that are useful in the bodies of
INITIALIZE-INSTANCE methods. The function SLOT-BOUNDP returns a
boolean value that states whether the slot is bound or not; this allows
for writing :AFTER methods for INITIALIZE-INSTANCE that initialize slots
only if they have not already been initialized. The function
SLOT-MAKUNBOUND restores a slot to the uninitialized condition.
Implementations are permitted to make certain optimizations of
INITIALIZE-INSTANCE. The description of INITIALIZE-INSTANCE in Chapter
2 mentions the possible optimizations. One possible optimization has
the following impact on user-supplied methods: :BEFORE and :AROUND
methods for INITIALIZE-INSTANCE cannot rely on all the slots being
uninitialized.
SECTION: Procedural Definition of MAKE-INSTANCE
MAKE-INSTANCE behaves as if it were defined as follows, except that
certain optimizations are permitted:
(defmethod make-instance ((class standard-class) &rest initargs)
(setq initargs (default-initargs class initargs))
(check-initargs class initargs)
(let ((instance (apply #'allocate-instance class initargs)))
(apply #'initialize-instance instance initargs)
instance))
(defmethod make-instance ((class-name symbol) &rest initargs)
(apply #'make-instance (symbol-class class-name) initargs))
Users can customize this procedure at either the Programmer Interface
level, the Meta-object level, or both.
The Programmer Interface level includes using the :INITFORM, :INITARG,
and :DEFAULT-INITARGS options to DEFCLASS, and defining methods for
INITIALIZE-INSTANCE.
The Meta-object level supports extra customization by defining methods
for: DEFAULT-INITARGS, CHECK-INITARGS, and ALLOCATE-INSTANCE.
Chapter 3 documents each of these generic functions and the
system-supplied default methods.
As noted above, certain optimizations of the MAKE-INSTANCE procedure are
permitted. The description of INITIALIZE-INSTANCE in Chapter 2 mentions
some possible optimizations to this procedure. Additional
optimizations are possible, including inlining and constant-folding of
method lookup and method bodies, provided that the programming
environment either prohibits redefining these methods or updates
everything when they are redefined. One approach might be for
MAKE-INSTANCE to have a separate method for every class, which is
automatically written and compiled by the system.
Because of optimization, methods for the meta-object generic functions
listed may not actually be called on every call to MAKE-INSTANCE, or may
not receive exactly the arguments that would be expected. For example,
CHECK-INITARGS might actually be called before DEFAULT-INITARGS rather
than after, if it has already been determined that the default initargs
will pass CHECK-INITARGS.
>>>> Mechanical Tasks:
Page 1-8: inheritance of :initarg
The :INITARG slot-option is inherited from superclasses. The set of
initargs that initialize a given slot is the union of the sets of initargs declared
in :INITARG slot-options with the same slot name in the class and its
superclasses.
Page-9: inheritance of :default-initargs (the only class option that is
inherited)
The :DEFAULT-INITARGS class option is inherited; the set of initargs for
a class that are defaulted is the union of the sets of initargs
specified in :DEFAULT-INITARGS class options of the class and its
superclasses. When more than one default value form is supplied for a
given initarg, the default value form supplied by the class that appears
earliest in the class precedence list is used.
Page 1-21: Congruent Lambda-lists for All Methods of a Generic Function
Replace the old rules with the new ones.
Probably should add a note about on 1-21 about this:
The proposal assumes CL-Cleanup issue KEYWORD-ARGUMENT-NAME-PACKAGE:ANY, which
stated that the names of &key arguments do not have to be keyword symbols.
The terminology of CLtL is used for discussing keyword arguments, but it
should be understood that keyword names are not necessarily symbols in
the keyword package; that's just a default convention.
Page 2-15 (and onward) DEFCLASS section
Add :INITARG and :DEFAULT-INITARGS to the syntax diagram.
Add this info:
The :INITARG -name- slot-option -declares- an initarg named -name- and
-specifies- that this initarg initializes the slot to which the
slot-option is attached. -name- is any symbol. If the initarg has a
value, the value is stored into the slot and the slot's :INITFORM, if
any, is -not- evaluated. If no initarg specified to initialize a given
slot has a value, then the slot is initialized according to the
:INITFORM (if any). This slot option can appear any number of times.
The :DEFAULT-INITARGS option is followed by a list of alternating
initarg names and default-initarg forms. If one of these initargs does
not appear in the initarg list supplied to MAKE-INSTANCE, the
corresponding default-initarg form is evaluated, then the initarg name
and the form's value are added to the end of the initarg list. The form
is evaluated every time it is used. The lexical environment in which
this form is evaluated is the lexical environment in which DEFCLASS was
evaluated. The dynamic environment is the dynamic environment in which
MAKE-INSTANCE was called. The :DEFAULT-INITARGS option may be specified
more than once. However, an error is signaled if an initarg name
appears more than once in a single :DEFAULT-INITARGS option, or in more
than one :DEFAULT-INITARGS option for a single class.
>>>> Add descriptions of each of these functions to Chapter 2:
(MAKE-INSTANCE -class- &key -initargs-...) => -instance-
Users call this function to create objects. Class can be either a class or
the name of a class. Meta-users can define new methods for MAKE-INSTANCE
to replace the object-creation protocol. For details, see
the section "Object Creation and Initialization".
(INITIALIZE-INSTANCE instance &key &allow-other-keys)
MAKE-INSTANCE calls this with the freshly-created instance, any initargs that
were supplied to MAKE-INSTANCE, and any defaulted initargs. Users define
methods for this to create method-implemented initargs. Typically,
user-defined methods are :AFTER methods, however that is not a requirement.
The primary method for INITIALIZE-INSTANCE is system-supplied and takes care
of the slot-filling initargs. For each slot (whether local or shared):
- if an initarg was specified or defaulted that fills that slot, its
value is stored into the slot. (This is true even if a :BEFORE method
has modified the slot.)
- otherwise, if the slot is uninitialized and it has an initform, the
initform is evaluated and the result is stored into the slot.
- the duplicate-resolution rules mentioned in the section "Rules for
Duplication of Initargs" are obeyed.
Implementations are permitted to optimize initforms that neither
produce nor depend on side-effects, by evaluating them and storing them
into slots before running any INITIALIZE-INSTANCE methods, rather than
handling them in the primary INITIALIZE-INSTANCE method. (This might be
implemented by having the ALLOCATE-INSTANCE method copy a prototype
instance.)
Implementations are permitted to optimize default value forms for
slot-filling initargs by not actually consing the complete initarg list,
when the only method that would see the complete list is the
system-supplied primary method, e.g. when no other methods use &REST.
In this case default value forms can be treated like initforms. This
has no visible effects other than a performance improvement.
(SLOT-BOUNDP instance slot-name) => boolean
Allows writing INITIALIZE-INSTANCE :AFTER methods that only initialize slots if
they haven't been initialized already.
(SLOT-MAKUNBOUND instance slot-name) => instance
Restores a slot to the uninitialized condition.
>>>> Add descriptions of each of these functions to Chapter 3
>>> Functions underlying the tools
It is undefined what happens if you modify the values returned by any
of the functions in this section. It is permitted, but not required,
for an implementation to return values that share with internal data
structures. Some of these functions will be SETF'able; which ones
remain to be determined.
(CLASS-ALL-INITARGS class) => list of initarg names, including inherited
ones. This is (REDUCE #'UNION (MAPCAR #'CLASS-DIRECT-INITARGS cpl)).
(CLASS-DIRECT-INITARGS class) => list of initarg names. This works by
computing the applicable methods for ALLOCATE-INSTANCE and for
INITIALIZE-INSTANCE and examining their lambda-lists (using
METHOD-KEYWORD-NAMES), then combining that with the class's list of
slot-filling initargs.
(CLASS-ALL-INITARG-DEFAULTS class)
=> ((initarg-name default-value-function default-value-form)...)
(CLASS-DIRECT-INITARG-DEFAULTS class)
=> ((initarg-name default-value-function default-value-form)...)
This reflects the :DEFAULT-INITARGS option. Default-value-form is the form
that was originally specified, and is retained purely for explanatory
purposes. default-value-function is what gets actually called; its effect is
equivalent to enclosing default-value-form in the appropriate lexical
environment. Default-value-function takes no arguments.
(CLASS-ALL-SLOT-INITARGS class) => ((initarg-name slot-name...)...)
(CLASS-DIRECT-SLOT-INITARGS class) => ((initarg-name slot-name...)...)
This reflects the :INITARG slot-option.
(COMPUTE-APPLICABLE-METHODS generic argument-list) => list of methods
(METHOD-KEYWORD-NAMES method) => list of symbols or &ALLOW-OTHER-KEYS,
indicating the keyword names of the keyword parameter specifiers in
the method's lambda-list. The result is the symbol &ALLOW-OTHER-KEYS
instead of a list if the method's lambda-list contains that symbol.
>>> Meta-object functions
(ALLOCATE-INSTANCE class &key &allow-other-keys) => instance
Meta-users can replace the system-supplied, implementation-dependent method
for this. Any keyword arguments accepted by applicable ALLOCATE-INSTANCE
methods become valid initargs.
(CHECK-INITARGS class initarg-list)
Meta-users could replace the system-supplied method that implements the
normal rules for initarg validity.
(DEFAULT-INITARGS class initarg-list) => initarg-list
The system-supplied method implements the :DEFAULT-INITARGS class option
by appending initargs that do not appear in initarg-list to the end
of the returned list. The initarg-list supplied as an argument is not
modified. The order of initargs appended to the list is determined by
the duplicate-initarg rules listed earlier.
(FINALIZE-INHERITANCE class &key slots methods initargs)
This is called by the system at least once before a class is instantiated, and
is called again whenever anything relevant changes. System-supplied methods
for this conspire with methods for CHECK-INITARGS, etc., to make MAKE-INSTANCE
faster. Users with their own optimization needs can add methods for this
generic function that will precompute things based on inherited information,
and update the precomputed information whenever anything changes.
The :slots, :methods, and :initargs arguments are booleans that are true
when the specified type of inheritance needs to be recomputed.
∂12-Oct-87 1814 Moon@STONY-BROOK.SCRC.Symbolics.COM Object Creation Writeup
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 12 Oct 87 18:14:42 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 253752; Mon 12-Oct-87 21:15:43 EDT
Date: Mon, 12 Oct 87 21:15 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Object Creation Writeup
To: Common-Lisp-Object-System@sail.stanford.edu
In-Reply-To: <19871013010341.1.MOON@EUPHRATES.SCRC.Symbolics.COM>
Message-ID: <19871013011546.3.MOON@EUPHRATES.SCRC.Symbolics.COM>
The fact that constructors are completely missing from the referenced
message indicates that I'm treating constructors as a separable issue.
It does not indicate that I think CLOS should not have constructors.
I'm still digesting the mail on the subject (some of which is giving
me indigestion).
∂13-Oct-87 0910 @Score.Stanford.EDU:kempf%hplabsz@hplabs.HP.COM Name Change for Metaobject Protocol?
Received: from SCORE.STANFORD.EDU by SAIL.STANFORD.EDU with TCP; 13 Oct 87 09:10:06 PDT
Received: from hplabs.HP.COM (hplabs.hpl.hp.com.#Internet) by SCORE.STANFORD.EDU with TCP; Tue 13 Oct 87 09:08:54-PDT
Received: from hplms2 by hplabs.HP.COM with SMTP ; Tue, 13 Oct 87 09:10:05 PDT
Received: from hplabsz.hpl.hp.com by hplms2; Tue, 13 Oct 87 12:09:43 edt
Return-Path: <kempf@hplabsz>
Received: from hplabsz by hplabsz; Tue, 13 Oct 87 10:10:49 pdt
To: common-lisp-object-system@sail.stanford.edu
Subject: Name Change for Metaobject Protocol?
X-Mailer: mh6.5
Date: Tue, 13 Oct 87 10:10:47 MDT
Message-Id: <3225.561139847@hplabsz>
From: kempf%hplabsz@hplabs.HP.COM
I'd like to suggest consideration of a name change for the metaobject
protocol. There were a number of occurances at OOPSLA which lead
me to think this may be a good idea. The one which stands out best
in my mind is Pierre Cointe's presentation at the CLOS working group,
where he presented an example of a metaclass (METAPOLYGON) which was
a metaclass in the Smalltalk sense, but not in the CLOS sense.
From talking to other people, this misconception seemed widespread.
My understanding about what we mean by the metaobject or metaclass
protocol is a collection of classes and methods which can be used
to implement new object oriented languages or extend the semantics of the
CLOS user level language, in a manner similar to the way macros can be used
to extend the syntax of Lisp. Additionally, one could look at the CLOS
metaclass protocol as a restricted version of Pattie Mais' reflection,
in the sense that it is a way of interrogating or modifying the language
semantics. What we do not mean is a class which acts as a "factory
instance" for creating and initializing classes, or a class which somehow
acts as a prototype (in the delegation sense) for other classes, though
one could use the metaobject protocol to define a metaclass which did
that.
As start, I'd like to suggest two possible names. Once is macro protocol or
semantic macro protocol, to draw an analogy with syntactic macros. The other is
reflective level protocol. The advantage of the first is that current Lisp
users will be able to make easy contact with it, the advantage of the
second is that it is perhaps more precise.
This issue may sound trivial, but, unfortunately, we are burdened with
history here, since Smalltalk and Objective-C have already appropriated
the name. While most Lisp programmers may not be bothered by this,
the confusion in OO circles is definitely there.
∂13-Oct-87 0930 Bobrow.pa@Xerox.COM Re: Name Change for Metaobject Protocol?
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 13 Oct 87 09:30:06 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 13 OCT 87 09:29:56 PDT
Date: 13 Oct 87 09:29 PDT
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Re: Name Change for Metaobject Protocol?
In-reply-to: kempf%hplabsz@hplabs.HP.COM's message of Tue, 13 Oct 87
10:10:47 MDT
To: kempf%hplabsz@hplabs.HP.COM
cc: common-lisp-object-system@sail.stanford.edu
Message-ID: <871013-092956-4931@Xerox>
My understanding about what we mean by the metaobject or
metaclass protocol is a collection of classes and methods which can
be used to implement new object oriented languages or extend the
semantics of the CLOS user level language, in a manner similar to
the way macros can be used to extend the syntax of Lisp.
Additionally, one could look at the CLOS metaclass protocol as a
restricted version of Pattie Mais' reflection, in the sense that it
is a way of interrogating or modifying the language semantics.
We do mean this, but not only this.
What we do not mean is a class which acts as a "factory
instance" for creating and initializing classes, or a class which
somehow acts as a prototype (in the delegation sense) for other
classes, though one could use the metaobject protocol to define a
metaclass which did that.
We also mean this. It is important to note that having access to the
implementation level of the object system c(the metaobject protocol) an
facilitate making trivial changes as well as more far reaching one. We
do not want to separate ourselves from these.
Hence I believe the name is well chosen, though I would not mind a well
chosen phrase usining "reflection" However, since our metaobject
protocol encompasses both the trivial things that Smalltalk metaclasses
do, as well as the reflective things that Pattie Maes does, and most
people do not know the term reflection, I think we are OK the way we
are.
∂13-Oct-87 1021 Gregor.pa@Xerox.COM Name Change for Metaobject Protocol?
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 13 Oct 87 10:21:03 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 13 OCT 87 10:21:23 PDT
Date: Tue, 13 Oct 87 10:21 PDT
From: Gregor.pa@Xerox.COM
Subject: Name Change for Metaobject Protocol?
To: kempf%hplabsz@hplabs.HP.COM
cc: common-lisp-object-system@sail.stanford.edu
In-Reply-To: <3225.561139847@hplabsz>
Message-ID: <871013102112.0.GREGOR@SPIFF.isl.parc.xerox.com>
Line-fold: no
Note: I apologize in advance for the terseness of this message. All the
messages I will be sending for a while will be compact as well; Its hard
to type with one hand.
The objects in the meta-object protocol are the objects which implement
the (metacircular) evaluator. So the current name is just right.
It is true than one can implement other sorts of object systems by
modifying the CLOS interpreter (using the meta object protocol). These
can be reflective or not, the key fact is that we have made the
interpreter accessible and that it is metacircular.
-------
∂13-Oct-87 1052 Gregor.pa@Xerox.COM fixing our problems with setf
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 13 Oct 87 10:52:14 PDT
Received: from Semillon.ms by ArpaGateway.ms ; 13 OCT 87 10:52:53 PDT
Date: Tue, 13 Oct 87 10:51 PDT
From: Gregor.pa@Xerox.COM
Subject: fixing our problems with setf
To: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
cc: Common-Lisp-Object-System@SAIL.STANFORD.EDU
In-Reply-To: <19871012205211.7.MOON@EUPHRATES.SCRC.Symbolics.COM>
Message-ID: <871013105134.3.GREGOR@SPIFF.isl.parc.xerox.com>
Line-fold: no
Date: Mon, 12 Oct 87 16:52 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
After thinking it over, I think Gregor's proposal to simplify the
way setf-functions work is reasonable. There will be some adoption
cost for us, because the order of arguments to a setf function is
being changed from what we agreed on before, but I think we can
come up with a compatibility kludge to take care of that. Of course,
Gregor's proposal doesn't really eliminate the scoping issues, not
only because we cannot get rid of defsetf and define-setf-method,
but also because of the already defined interaction of setf with
macros. However, I think the scoping rules are quite
straightforward.
Right, what it does do is make the scoping rules simpler and allows a
style in which there is no desire to lexically bind setf macros.
Here is a revised version of what I mailed out on September 28,
modified and simplified to reflect what Gregor proposed:
I just have a couple of comments on your writeup.
As with regular functions, associated with any given name you can have a
setf function or a setf macro, but not both. This means that one does
not define a setf function (with defmethod or defgeneric) and also call
defsetf. The mere act of defining the setf function is enough to tell
setf what to do. In fact setf only needs for the setf function to be
defined at run time, not at compile time.
2 comments
* one could very well have defsetf of FOO and a function named (setf
foo). This might be weird, but nothing prevents it from happening.
* the meaning of the last sentence would be more clear if the next to
the last sentence was removed and the last sentence changed to:
"In the absence of any setf macro definition, SETF expands into a call
to the setf function. This means that the setf function only needs to
be defined at run time, not compile time."
I would like to see what you send to cleanup beforehand if possible.
But I do not expect to read my mail the last half of this week or the
first half of next, so that might make it impossible.
-------
∂13-Oct-87 1103 Gregor.pa@Xerox.COM Extent of CALL-NEXT-METHOD
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 13 Oct 87 11:03:20 PDT
Received: from Salvador.ms by ArpaGateway.ms ; 13 OCT 87 10:55:53 PDT
Date: Tue, 13 Oct 87 10:55 PDT
From: Gregor.pa@Xerox.COM
Subject: Extent of CALL-NEXT-METHOD
To: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
cc: common-lisp-object-system@SAIL.Stanford.EDU
In-Reply-To: <19871012205849.8.MOON@EUPHRATES.SCRC.Symbolics.COM>
Message-ID: <871013105540.4.GREGOR@SPIFF.isl.parc.xerox.com>
Line-fold: no
Date: Mon, 12 Oct 87 16:58 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Date: Mon, 12 Oct 87 13:29 PDT
From: Gregor.pa@Xerox.COM
It seems to me that this has to do with whether defmethod (and friends)
replace the existing method or alter the existing method. I thought
defmethod replaced the existing method; so it seems to me that if the
closure captures the method objects redefining one of the captured
methods should have no effect on the closure.
defmethod should behave consistently with defclass and defgeneric in
this respect. The latter two alter an existing object rather than
creating a new object.
I am not sure that these nust behave consistently. The objects being
defined are different. A class is a large complex structure which is
linked with a lot of things, experience has shown it is useful to update
rather than replace it. A method is smaller and less linked, it may be
reasonable to replace rather than update it. I don't have a really
strong opinion about this (yet), I just wanted to point out that I don't
see consistency as a particularly strong argument here.
-------
∂13-Oct-87 1103 Gregor.pa@Xerox.COM reinitializing class slots
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 13 Oct 87 11:03:25 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 13 OCT 87 11:00:55 PDT
Date: Tue, 13 Oct 87 11:00 PDT
From: Gregor.pa@Xerox.COM
Subject: reinitializing class slots
To: Patrick H Dussud <DUSSUD@Jenner.csc.ti.com>
cc: Danny Bobrow <Bobrow.pa@Xerox.COM>,
Common-Lisp-Object-System@sail.stanford.edu
In-Reply-To: <2770054846-7184236@Jenner>
Message-ID: <871013110025.6.GREGOR@SPIFF.isl.parc.xerox.com>
Line-fold: no
Date: Mon, 12 Oct 87 14:40:46 CDT
From: Patrick H Dussud <DUSSUD@Jenner.csc.ti.com>
If we think of those slots as shared instead of class slots, then the
issue of consistency of behavior with local slots becomes more important.
They shouldn't be reinitialized when the class gets redefined.
I agree.
-------
∂13-Oct-87 1114 Moon@STONY-BROOK.SCRC.Symbolics.COM fixing our problems with setf
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 13 Oct 87 11:14:39 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 254248; Tue 13-Oct-87 14:15:33 EDT
Date: Tue, 13 Oct 87 14:15 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: fixing our problems with setf
To: Common-Lisp-Object-System@SAIL.STANFORD.EDU
In-Reply-To: <871013105134.3.GREGOR@SPIFF.isl.parc.xerox.com>
Message-ID: <19871013181532.3.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Tue, 13 Oct 87 10:51 PDT
From: Gregor.pa@Xerox.COM
I just have a couple of comments on your writeup.
I would like to see what you send to cleanup beforehand if possible.
But I do not expect to read my mail the last half of this week or the
first half of next, so that might make it impossible.
I think resolving this setf stuff is important, so I will attempt to
send out a revised version of my proposal, plus a cleanup committee
proposal, later today, to try to give you time to comment on it.
Have as good a time as it is possible to have in a hospital.
∂13-Oct-87 1348 Moon@STONY-BROOK.SCRC.Symbolics.COM fixing our problems with setf
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 13 Oct 87 13:48:20 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 254492; Tue 13-Oct-87 16:45:14 EDT
Date: Tue, 13 Oct 87 16:45 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: fixing our problems with setf
To: Gregor.pa@Xerox.COM
cc: Common-Lisp-Object-System@SAIL.STANFORD.EDU
In-Reply-To: <871013105134.3.GREGOR@SPIFF.isl.parc.xerox.com>
Message-ID: <19871013204504.5.MOON@EUPHRATES.SCRC.Symbolics.COM>
Line-fold: No
Here is the proposal I will send to the cleanup committee Wednesday
evening, after incorporating any comments you have to offer:
Issue: SETF-CLOS
References: setf rules for what -place- can be (pp.94-7)
compile function (p.438)
defun macro (p.57)
disassemble function (p.439)
documentation function (p.440)
fboundp function (p.90)
flet special form (p.113)
fmakunbound function (p.92)
ftype declaration (p.158)
function special form (p.87)
function declaration (p.159)
inline declaration (p.159)
notinline declaration (p.159)
labels special form (p.113)
symbol-function and setf of symbol-function (p.90)
trace macro (p.440)
untrace macro (p.440)
Category: ADDITION
Edit history: Version 1, 13-Oct-87 Moon
Problem description:
The Common Lisp Object System needs a well-defined way to relate the
name and arguments of a setting function to those of a reading function,
because both functions can be generic and can have user-defined methods.
We tried to hide the name and arguments of the setting function with
macrology, but the complexity got out of hand. It seems better to make
this information explicit; the version of the CLOS specification that
assumes the adoption of proposal SETF-CLOS:SETF-FUNCTIONS is much
simpler in the relevant areas.
Proposal (SETF-CLOS:SETF-FUNCTIONS):
Add to Common Lisp the concept of "setf functions". Right now, Common
Lisp only has "setf macros", which are defined by define-setf-method and
both forms of defsetf. Terminology:
- a "setf macro" is something that produces code (or other
specifications, as in define-setf-method) which, when evaluated,
will perform the effect of an invocation of setf.
- a "setf function" is something that is called to perform
directly the effect of an invocation of setf.
The name of the setf function that is called to perform the effect of
(setf (-name- ...) ...) is a list (setf -name-), where -name- is a
symbol. The functions, macros, and special forms defined in CLtL and
listed in the References section above need to be enhanced to accept
such lists in addition to symbols as function names.
A setf function receives the new value to be stored as its first
argument. Thus, #'(setf foo) should have one more required parameter
than #'foo, the first required parameter is the new value to be stored,
and the remaining parameters should be the same as #'foo's parameters.
A setf function must return its first argument, since setf is defined
to return the new value.
A definition of a setf function can be lexically local, like a
definition of a reading function. The following rules specify the
behavior of SETF; note that these rules are ordered and the first rule
to apply supersedes any later rules. These rules are a consistent
extension of the current behavior of Common Lisp and the Cleanup
committee's resolution of issue GET-SETF-METHOD-ENVIRONMENT. Only
rule 4 is new with this proposal.
Rules for the macroexpansion of (setf (foo x) y):
(1) If the function-name foo refers to the global function definition,
rather than a locally defined function or macro, and if there is a
setf macro defined for foo, use the setf macro to compute the expansion.
(2) If the function-name foo is defined as a macro in the current scope,
use macroexpand-1 to expand (foo x) and try again.
(3) If the function-name foo is defined as a special form in the current
scope, signal an error.
(4) Expand into the equivalent of
(let ((#:temp-1 x)
(#:temp-2 y))
(funcall #'(setf foo) #:temp-2 #:temp-1))
Note that rule 4 is independent of the scope of the function name
(setf foo). It does not matter if that scope is different from the
scope of the function name foo. This allows some nonsensical programs
to be written, but does not seem harmful enough to justify making more
complicated rules to compare the scopes of the two function definitions.
Normally one does not define both a setf function and a setf macro
for the same reading function.
Normally one defines a local reading function and a local setf function
together in a single FLET or LABELS.
In the absence of any setf macro definition, SETF of a function expands
into a call to the setf function. This means that the setf function
only needs to be defined at run time, not compile time.
Test Case: (really more of an example than a test case)
;If setf of subseq was not already built into Common Lisp,
;it could have been defined like this
(defun (setf subseq) (new-value sequence start &optional end)
(unless end (setq end (length sequence)))
(setq end (min end (+ start (length new-value))))
(do ((i start (1+ i))
(j 0 (1+ j)))
((= i end) new-value)
(setf (elt sequence i) (elt new-value j))))
Rationale:
By making the names and arguments of setting functions explicit, CLOS is
considerably simplified.
Current practice:
A few Common Lisp implementations already have a similar feature,
in that they have setting functions named (SETF reader). I don't
know of any implementation that has precisely the proposed feature.
Adoption Cost:
The main cost is generalization of a few functions to accept lists
beginning with SETF where they now accept only symbols. Implementations
must add a data structure to store the function definition of a setf
function, however, this can trivially be done with property lists or
generated symbols.
The cost of making the SETF macro expand into a call to a setf function,
when it does not find a setf macro or a regular macro to expand, is
negligible.
This will be an incompatible change for Symbolics, since it already has
setf functions but they do not take the same arguments as proposed here.
However, the change is considered worthwhile.
Cost of non-adoption:
Non-adoption of this proposal would be a significant roadblock to the
Common Lisp Object System. Some major rethinking of CLOS would be
required.
Benefits:
Allow CLOS to be defined without out-of-hand complexity.
Conversion Cost:
None, this is an upward-compatible change.
Esthetics:
SETF would be more esthetic, but less powerful, if it had only the
proposed setf functions and did not have setf macros. Such a major
incompatible change is of course out of the question, however by
stressing setf functions SETF could become easier to teach.
Discussion:
Note that in Common Lisp, setf macroexpansion is an operation on
function names, not on functions. It differs from some dialects of
Scheme, such as T, in this respect. This proposal does not attempt to
change that.
The following related features were considered but are specifically
not being proposed at this time, since they are unnecessary for CLOS
and appear not to improve the simplicity and esthetics of the language:
Lexically local setf macros, that is, a cross between defsetf and
macrolet. This does not appear to be logically necessary. Do all three
ways of defining lexically global setf macros need local counterparts?
Should we define the meaning of defmacro or macrolet of (setf foo)?
This would be a fourth way to define a setf macro.
Should we enhance the definition of global setf macros, for example to
say that (macro-function '(setf foo)) returns an expander function that
takes two arguments and returns five values?
Should we introduce a new name for symbol-function, since it accepts
non-symbols now?
∂13-Oct-87 1427 RPG Status
To: common-lisp-object-system@SAIL.Stanford.EDU
LGD and I are working (like mad) on the spec. I am concentrating
on the concepts chapter and Linda on the functions chapter.
Slot description inheritance, congruence, and 1/3 of the object
creation sections supplied by Moon have been incorporated into
the concepts chapter. As I go I am building up a list of
further minor tasks. This list slowly increases, so that I doubt
that we can meet the Oct 16 deadline for completion of the first
pass of the rewrite. I expect that mid-to-late next week is more like
it.
This will require very fast turnaround from you folks on the draft.
-rpg-
∂13-Oct-87 1436 Moon@STONY-BROOK.SCRC.Symbolics.COM fixing our problems with setf
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 13 Oct 87 14:36:09 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 254575; Tue 13-Oct-87 17:36:18 EDT
Date: Tue, 13 Oct 87 17:36 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: fixing our problems with setf
To: Common-Lisp-Object-System@SAIL.STANFORD.EDU
In-Reply-To: <871013105134.3.GREGOR@SPIFF.isl.parc.xerox.com>
Message-ID: <19871013213622.1.MOON@EUPHRATES.SCRC.Symbolics.COM>
Here is a revision of what I mailed out yesterday, revised to reflect
Gregor's comments. If this differs from the CL-cleanup draft proposal
I mailed out a few minutes ago, that proposal supersedes this one.
The goal is to unify the handling of "setf functions" with the handling
of regular functions, so we don't need a proliferation of -setf versions
of defmethod, defgeneric, ensure-generic-function, fboundp, generic-labels,
with-added-methods, etc. The major issue is that Common Lisp has not seen
a need to do this already, so the onus falls on CLOS. In addition, we
ran into difficulty with confusion between the idea of associating a
function name with a function object (in our case, a generic function
object), and the idea of associating a way to setf a function with that
function. This proposal clarifies the situation.
Add to Common Lisp the same concept of "setf functions" that we are
already introducing in CLOS. Right now, Common Lisp only has "setf
macros", which are defined by define-setf-method and both forms of
defsetf. I draw the distinction because a "setf macro" is something
that produces code (or other specifications, as in define-setf-method)
which, when evaluated, will perform the effect of an invocation of setf,
while a "setf function" is something that is called to perform directly
the effect of an invocation of setf.
Since setf functions are in a separate, but parallel, namespace from
regular functions, we need a way to name them. The simplest way is to
allow a list (setf -name-) to be used as the name of the setf function
that is called to perform the effect of (setf (-name- ...) ...). The
following functions, macros, and special forms defined in CLtL need to
be enhanced to accept such lists where they now accept symbols as
function names:
compile
defun
disassemble
documentation
fboundp
flet
fmakunbound
function
labels
symbol-function and setf of symbol-function
trace
untrace
and the declarations ftype, function, inline, and notinline
This makes the name of symbol-function a bit obsolete, but I do not
propose to introduce a new function to replace it. The discrepancy is
not that important.
The following functions, macros, and special forms defined in CLOS need
to be enhanced in the same way:
defgeneric
defmethod
ensure-generic-function
generic-flet
generic-labels
with-added-methods
defmethod-setf and defgeneric-setf need to be removed.
A setf function receives the new value to be stored as its first
argument. Thus, #'(setf foo) should have one more required parameter
than #'foo, the first required parameter is the new value to be stored,
and the remaining parameters should be the same as #'foo's parameters.
A setf function must return its first argument, since setf is defined
to return the new value.
Normally one does not define both a setf function and a setf macro
for the same reading function.
A definition of a setf function can be lexically local, like a
definition of a reading function.
Normally one defines a local reading function and a local setf function
together in a single FLET, LABELS, GENERIC-FLET, GENERIC-LABELS, or
WITH-ADDED-METHODS.
In the absence of any setf macro definition, SETF of a function expands
into a call to the setf function. This means that the setf function
only needs to be defined at run time, not compile time.
Note that in Common Lisp, setf macroexpansion is an operation on
function names, not on functions. It differs from some dialects of
Scheme, such as T, in this respect. This proposal does not attempt to
change that.
Note that I do not propose to introduce lexically local setf macros,
that is, a cross between defsetf and macrolet. This does not appear to
be logically necessary. If someone else wants this, it would certainly
not be hard to do. The main issue is whether all three ways of defining
lexically global setf macros need local counterparts. A secondary issue
is whether to define the meaning of defmacro or macrolet of (setf foo).
I also do not now propose to enhance the definition of global setf
macros, for example to say that (macro-function '(setf foo)) returns an
expander function that takes two arguments and returns five values.
These issues logically belong to Common Lisp, not to CLOS.
Contrary to what we already decided about the lambda-list of a
setf-function, the new value to be stored will be passed as the first
argument.
The function-defining macros defun, flet, labels, defgeneric, defmethod,
and the :method option to defgeneric, generic-flet, generic-labels, and
with-added-methods will not have a special syntax with two lambda-lists
when defining a setf function, contrary to what we decided before. The
programmer writing a setf-function must know to insert the new-value
parameter at the front of the lambda-list.
The remaining issue is a scoping issue. We have introduced lexically
local setf functions, where before Common Lisp only had lexically global
setf macros. Thus the namespace of setf operators has been extended to
have a lexical component, just like the namespace of regular operators.
(Recall that "operator" means the union of functions, macros, and
special forms). Regular functions and setf functions naturally come in
pairs, but since they are defined separately we have to specify what
happens in various cases where only one is defined at a given lexical
contour. The following rules for the behavior of SETF suffice; note
that these rules are ordered and the first rule to apply supersedes any
later rules. These rules are a consistent extension of the current
behavior of Common Lisp and the Cleanup committee's resolution of issue
GET-SETF-METHOD-ENVIRONMENT. Only rule 4 is new with this proposal.
Rules for the macroexpansion of (setf (foo x) y):
(1) If the function-name foo refers to the global function definition,
rather than a locally defined function or macro, and if there is a
setf-macro defined for foo, use the setf-macro to compute the expansion.
(2) If the function-name foo is defined as a macro in the current scope,
use macroexpand-1 to expand (foo x) and try again.
(3) If the function-name foo is defined as a special form in the current
scope, signal an error.
(4) Expand into the equivalent of
(let ((#:temp-1 x)
(#:temp-2 y))
(funcall #'(setf foo) #:temp-2 #:temp-1))
Note that rule 4 is independent of the scope of the function name
(setf foo) and does not care if that scope is different from the scope
of the function name foo. This allows some nonsensical programs to
be written, but does not seem harmful enough to justify making the
rules more complicated.
Example (for Patrick):
(defmethod (setf subseq)
((new-value vector) (sequence vector) start &optional end)
(unless end (setq end (length sequence)))
(setq end (min end (+ start (length new-value))))
(do ((i start (1+ i))
(j 0 (1+ j)))
((= i end) new-value)
(setf (aref sequence i) (aref new-value j))))
∂13-Oct-87 1459 Gregor.pa@Xerox.COM fixing our problems with setf
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 13 Oct 87 14:59:00 PDT
Received: from Semillon.ms by ArpaGateway.ms ; 13 OCT 87 14:59:16 PDT
Date: Tue, 13 Oct 87 14:59 PDT
From: Gregor.pa@Xerox.COM
Subject: fixing our problems with setf
To: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
cc: Gregor.pa@Xerox.COM, Common-Lisp-Object-System@SAIL.STANFORD.EDU
In-Reply-To: <19871013204504.5.MOON@EUPHRATES.SCRC.Symbolics.COM>
Message-ID: <871013145903.8.GREGOR@SPIFF.isl.parc.xerox.com>
Line-fold: no
Date: Tue, 13 Oct 87 16:45 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
I have just a couple of comments. I put them in as comments rather than
editing your text so it would be easier to see them. Otherwise this
looks good, it seems the best compromise between what I have been
wanting to do with setf for sometime and backward compatibility.
Here is the proposal I will send to the cleanup committee Wednesday
evening, after incorporating any comments you have to offer:
Issue: SETF-CLOS
References: setf rules for what -place- can be (pp.94-7)
compile function (p.438)
defun macro (p.57)
disassemble function (p.439)
documentation function (p.440)
fboundp function (p.90)
flet special form (p.113)
fmakunbound function (p.92)
ftype declaration (p.158)
function special form (p.87)
function declaration (p.159)
inline declaration (p.159)
notinline declaration (p.159)
labels special form (p.113)
symbol-function and setf of symbol-function (p.90)
trace macro (p.440)
untrace macro (p.440)
Category: ADDITION
Edit history: Version 1, 13-Oct-87 Moon
Problem description:
The Common Lisp Object System needs a well-defined way to relate the
name and arguments of a setting function to those of a reading function,
because both functions can be generic and can have user-defined methods.
We tried to hide the name and arguments of the setting function with
macrology, but the complexity got out of hand. It seems better to make
this information explicit; the version of the CLOS specification that
assumes the adoption of proposal SETF-CLOS:SETF-FUNCTIONS is much
simpler in the relevant areas.
Proposal (SETF-CLOS:SETF-FUNCTIONS):
Add to Common Lisp the concept of "setf functions". Right now, Common
Lisp only has "setf macros", which are defined by define-setf-method and
both forms of defsetf. Terminology:
- a "setf macro" is something that produces code (or other
specifications, as in define-setf-method) which, when evaluated,
will perform the effect of an invocation of setf.
- a "setf function" is something that is called to perform
directly the effect of an invocation of setf.
You should say right here that a setf function is called by the default
expansion of setf (unless a setf macro was explicitly defined).
The name of the setf function that is called to perform the effect of
(setf (-name- ...) ...) is a list (setf -name-), where -name- is a
symbol. The functions, macros, and special forms defined in CLtL and
listed in the References section above need to be enhanced to accept
such lists in addition to symbols as function names.
A setf function receives the new value to be stored as its first
argument. Thus, #'(setf foo) should have one more required parameter
than #'foo, the first required parameter is the new value to be stored,
and the remaining parameters should be the same as #'foo's parameters.
A setf function must return its first argument, since setf is defined
to return the new value.
A definition of a setf function can be lexically local, like a
definition of a reading function. The following rules specify the
behavior of SETF; note that these rules are ordered and the first rule
to apply supersedes any later rules. These rules are a consistent
extension of the current behavior of Common Lisp and the Cleanup
committee's resolution of issue GET-SETF-METHOD-ENVIRONMENT. Only
rule 4 is new with this proposal.
Rules for the macroexpansion of (setf (foo x) y):
(1) If the function-name foo refers to the global function definition,
rather than a locally defined function or macro, and if there is a
setf macro defined for foo, use the setf macro to compute the expansion.
(2) If the function-name foo is defined as a macro in the current scope,
use macroexpand-1 to expand (foo x) and try again.
(3) If the function-name foo is defined as a special form in the current
scope, signal an error.
(4) Expand into the equivalent of
(let ((#:temp-1 x)
(#:temp-2 y))
(funcall #'(setf foo) #:temp-2 #:temp-1))
Note that rule 4 is independent of the scope of the function name
(setf foo). It does not matter if that scope is different from the
scope of the function name foo. This allows some nonsensical programs
to be written, but does not seem harmful enough to justify making more
complicated rules to compare the scopes of the two function definitions.
Normally one does not define both a setf function and a setf macro
for the same reading function.
Normally one defines a local reading function and a local setf function
together in a single FLET or LABELS.
(I give an example later).
In the absence of any setf macro definition, SETF of a function expands
into a call to the setf function. This means that the setf function
only needs to be defined at run time, not compile time.
Should be "Since in the absence of ..."?
Test Case: (really more of an example than a test case)
;If setf of subseq was not already built into Common Lisp,
;it could have been defined like this
(defun (setf subseq) (new-value sequence start &optional end)
(unless end (setq end (length sequence)))
(setq end (min end (+ start (length new-value))))
(do ((i start (1+ i))
(j 0 (1+ j)))
((= i end) new-value)
(setf (elt sequence i) (elt new-value j))))
Another example would be:
(defun frobulate (mumble)
(let ((table (mumble-table mumble)))
(flet ((foo (x)
(gethash x table))
((setf foo) (new x)
(setf (gethash x table) new)))
..
(foo a)
..
(setf (foo a) b))))
Rationale:
By making the names and arguments of setting functions explicit, CLOS is
considerably simplified.
This reduces the desire having a way to lexially bind setf macros
because code which doesn't use defsetf or define-modify-macro won't need
lexical setf macros it can just use lexical functions.
It would be good to point out that right now, many people are doing
something *like* this:
(defsetf foo |setf FOO|)
(defun foo (x) ..)
(defun |setf FOO| (x new) ..)
and that these many similar styles will all be able to be expressed
with:
(defun foo (x) ..)
(defun (setf foo) (new x) ..)
The bringing together of these styles will make code more 'common'. I
tried to capture this in the following paragraph but it doesn't quite
get it.
Many of the current styles of using setf are quite similar. That code
will be be simplified because many people who have been using techniques
essentially equivalent to using setf functions with no setf macros in
the new technique will begin using a common mechanism.
Current practice:
A few Common Lisp implementations already have a similar feature,
in that they have setting functions named (SETF reader). I don't
know of any implementation that has precisely the proposed feature.
Adoption Cost:
The main cost is generalization of a few functions to accept lists
beginning with SETF where they now accept only symbols. Implementations
must add a data structure to store the function definition of a setf
function, however, this can trivially be done with property lists or
generated symbols.
The cost of making the SETF macro expand into a call to a setf function,
when it does not find a setf macro or a regular macro to expand, is
negligible.
This will be an incompatible change for Symbolics, since it already has
setf functions but they do not take the same arguments as proposed here.
However, the change is considered worthwhile.
Cost of non-adoption:
Non-adoption of this proposal would be a significant roadblock to the
Common Lisp Object System. Some major rethinking of CLOS would be
required.
Benefits:
Allow CLOS to be defined without out-of-hand complexity.
Conversion Cost:
None, this is an upward-compatible change.
Esthetics:
SETF would be more esthetic, but less powerful, if it had only the
proposed setf functions and did not have setf macros. Such a major
incompatible change is of course out of the question, however by
stressing setf functions SETF could become easier to teach.
perhaps "by stressing the use of setf functions and no explicit setf
macros SETF could become easier to teach.".
I really believe that many people will stop defining setf macros once
this proposal is accepted.
Discussion:
Note that in Common Lisp, setf macroexpansion is an operation on
function names, not on functions. It differs from some dialects of
Scheme, such as T, in this respect. This proposal does not attempt to
change that.
The following related features were considered but are specifically
not being proposed at this time, since they are unnecessary for CLOS
and appear not to improve the simplicity and esthetics of the language:
Lexically local setf macros, that is, a cross between defsetf and
macrolet. This does not appear to be logically necessary. Do all three
ways of defining lexically global setf macros need local counterparts?
Should we define the meaning of defmacro or macrolet of (setf foo)?
This would be a fourth way to define a setf macro.
Should we enhance the definition of global setf macros, for example to
say that (macro-function '(setf foo)) returns an expander function that
takes two arguments and returns five values?
Should we introduce a new name for symbol-function, since it accepts
non-symbols now?
-------
∂13-Oct-87 1817 Bobrow.pa@Xerox.COM Re: fixing our problems with setf
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 13 Oct 87 18:17:45 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 13 OCT 87 18:18:23 PDT
Date: 13 Oct 87 18:18 PDT
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Re: fixing our problems with setf
In-reply-to: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>'s
message of Tue, 13 Oct 87 16:45 EDT
To: Moon@STONY-BROOK.SCRC.Symbolics.COM
cc: Gregor.pa@Xerox.COM, Common-Lisp-Object-System@SAIL.STANFORD.EDU
Message-ID: <871013-181823-5939@Xerox>
Rules for the macroexpansion of (setf (foo x) y):
(1) If the function-name foo refers to the global function
definition, rather than a locally defined function or macro, and if
there is a setf macro defined for foo, use the setf macro to
compute the expansion.
(2) If the function-name foo is defined as a macro in the
current scope, use macroexpand-1 to expand (foo x) and try again.
(3) If the function-name foo is defined as a special form in
the current scope, signal an error.
(4) Expand into the equivalent of
(let ((#:temp-1 x)
(#:temp-2 y))
(funcall #'(setf foo) #:temp-2 #:temp-1))
Do (1) and (4) together imply that if there is a macro definition for
foo, and there is an flet foo, but no (setf foo) defined, that the
expansion of
(setf (foo ...)...)
uses (funcall #'(setf foo) ...) rather than the macro. This seems wrong
(inconsistent with CLtL ???).
Normally one does not define both a setf function and a setf
macro for the same reading function.
But if a (setf foo) is defined locally, it is always be used, whether or
not foo is defined locally or globally, right???
I think the rule might be stated that if there is no (setf foo) function
AND there is a setf macro, then the macro is used, else the (setf foo)
function is used in the expansion. This is a slightly extended version
of your:
In the absence of any setf macro definition, SETF of a function
expands into a call to the setf function.
But aside from these two glitches (or my misunderstanding), I agree.
danny
∂13-Oct-87 1845 Pavel.pa@Xerox.COM Re: fixing our problems with setf
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 13 Oct 87 18:45:13 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 13 OCT 87 18:45:51 PDT
Date: Tue, 13 Oct 87 18:45:44 PDT
From: Pavel.pa@Xerox.COM
Subject: Re: fixing our problems with setf
In-reply-to: <871013-181823-5939@Xerox>
To: Danny Bobrow <Bobrow.pa@Xerox.COM>
Cc: Common-Lisp-Object-System@SAIL.STANFORD.EDU
Message-ID: <871013-184551-5973@Xerox>
Date: 13 Oct 87 18:18 PDT
From: Danny Bobrow <Bobrow.pa>
Do (1) and (4) together imply that if there is a macro definition for
foo, and there is an flet foo, but no (setf foo) defined, that the
expansion of
(setf (foo ...)...)
uses (funcall #'(setf foo) ...) rather than the macro. This seems wrong
(inconsistent with CLtL ???).
Isn't it the case that lexical functions cannot have a SETF method in
CLtL? I believe that in the following code:
(defsetf foo set-foo)
(flet ((foo (x) ...))
(setf (foo 7) 8))
the function SET-FOO will not be called. Instead, SETF should signal an
error complaining about how there isn't a SETF method for the lexical
function FOO. The SETF method for the global function FOO is not used.
Am I just hallucinating about this?
Pavel
∂13-Oct-87 1900 Moon@STONY-BROOK.SCRC.Symbolics.COM Re: fixing our problems with setf
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 13 Oct 87 19:00:02 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 254770; Tue 13-Oct-87 22:00:32 EDT
Date: Tue, 13 Oct 87 22:00 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: fixing our problems with setf
To: Pavel.pa@Xerox.COM
cc: Common-Lisp-Object-System@SAIL.STANFORD.EDU
In-Reply-To: <871013-184551-5973@Xerox>
Message-ID: <19871014020034.8.MOON@EUPHRATES.SCRC.Symbolics.COM>
Line-fold: No
Date: Tue, 13 Oct 87 18:45:44 PDT
From: Pavel.pa@Xerox.COM
Isn't it the case that lexical functions cannot have a SETF method in
CLtL?
CLtL doesn't say, but the CL-Cleanup committee decided about half a year
ago, in resolving issue GET-SETF-METHOD-ENVIRONMENT, that what you say
is true. See the handout from the June X3J13 meeting.
I believe that in the following code:
(defsetf foo set-foo)
(flet ((foo (x) ...))
(setf (foo 7) 8))
the function SET-FOO will not be called. Instead, SETF should signal an
error complaining about how there isn't a SETF method for the lexical
function FOO. The SETF method for the global function FOO is not used.
That's correct.
Am I just hallucinating about this?
If so, you're hallucinating the same way as the Cleanup committee.
∂13-Oct-87 1904 Moon@STONY-BROOK.SCRC.Symbolics.COM Re: fixing our problems with setf
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 13 Oct 87 19:04:24 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 254778; Tue 13-Oct-87 22:05:21 EDT
Date: Tue, 13 Oct 87 22:05 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: fixing our problems with setf
To: Common-Lisp-Object-System@SAIL.STANFORD.EDU
In-Reply-To: <871013-181823-5939@Xerox>
Message-ID: <19871014020527.9.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: 13 Oct 87 18:18 PDT
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Rules for the macroexpansion of (setf (foo x) y):
(1) If the function-name foo refers to the global function
definition, rather than a locally defined function or macro, and if
there is a setf macro defined for foo, use the setf macro to
compute the expansion.
(2) If the function-name foo is defined as a macro in the
current scope, use macroexpand-1 to expand (foo x) and try again.
(3) If the function-name foo is defined as a special form in
the current scope, signal an error.
(4) Expand into the equivalent of
(let ((#:temp-1 x)
(#:temp-2 y))
(funcall #'(setf foo) #:temp-2 #:temp-1))
Do (1) and (4) together imply that if there is a macro definition for
foo, and there is an flet foo, but no (setf foo) defined, that the
expansion of
(setf (foo ...)...)
uses (funcall #'(setf foo) ...) rather than the macro. This seems wrong
(inconsistent with CLtL ???).
CLtL doesn't say anything about calling #'(setf foo).
Yes, local function definitions shadow global macros and global setf macros.
This is what the cleanup committee already decided. See the handout from
the June X3J13 meeting, issue GET-SETF-METHOD-ENVIRONMENT.
A program that defines a local foo without defining a (setf foo) is an
example of the nonsensical programs alluded to in my message.
Normally one does not define both a setf function and a setf
macro for the same reading function.
But if a (setf foo) is defined locally, it is always be used, whether or
not foo is defined locally or globally, right???
setf is an operation on function names, not functions, so when we say
that a given form expands into (funcall #'(setf foo) ...), that is independent
of the scoping of (setf foo). Whatever (setf foo) is in scope gets called,
even if its scope is less than the scope of foo. Another way to write
nonsensical programs, perhaps. Of course one doesn't need setf at all
to write nonsensical programs!
I think the rule might be stated that if there is no (setf foo) function
AND there is a setf macro, then the macro is used, else the (setf foo)
function is used in the expansion. This is a slightly extended version
of your:
In the absence of any setf macro definition, SETF of a function
expands into a call to the setf function.
But aside from these two glitches (or my misunderstanding), I agree.
You've just restated the more complicated rule that Gregor just
convinced me to get rid of. Maybe you should talk to him (preferably
before he metamorphoses).
∂13-Oct-87 2009 Pavel.pa@Xerox.COM Re: fixing our problems with setf
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 13 Oct 87 20:09:28 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 13 OCT 87 20:07:00 PDT
Date: Tue, 13 Oct 87 20:01:00 PDT
From: Pavel.pa@Xerox.COM
Subject: Re: fixing our problems with setf
In-reply-to: <19871013204504.5.MOON@EUPHRATES.SCRC.Symbolics.COM>
To: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Cc: Common-Lisp-Object-System@SAIL.STANFORD.EDU
Message-ID: <871013-200700-6060@Xerox>
A nit in your test case. It would be nicer if the optional variable end
had a default value rather than using the (unless end ...) hack:
;If setf of subseq was not already built into Common Lisp,
;it could have been defined like this
(defun (setf subseq) (new-value sequence start &optional (end (length
sequence)))
(setq end (min end (+ start (length new-value))))
(do ((i start (1+ i))
(j 0 (1+ j)))
((= i end) new-value)
(setf (elt sequence i) (elt new-value j))))
∂14-Oct-87 0827 @STONY-BROOK.SCRC.Symbolics.COM,@JUNCO.SCRC.Symbolics.COM:skeene@STONY-BROOK.SCRC.Symbolics.COM status of "object" or "standard-object"
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 14 Oct 87 08:27:26 PDT
Received: from JUNCO.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via INTERNET with SMTP id 255053; 14 Oct 87 11:28:07 EDT
Date: Wed, 14 Oct 87 11:27 EDT
From: Sonya E. Keene <skeene@STONY-BROOK.SCRC.Symbolics.COM>
Subject: status of "object" or "standard-object"
To: common-lisp-object-system@sail.stanford.edu
Message-ID: <871014112750.2.SKEENE@JUNCO.SCRC.Symbolics.COM>
Last month we discussed whether CLOS should specify the class "object"
or "standard-object", and we didn't get anywhere.
To me, this seems to be a hole in the spec that we ought to fill up in
time for the next draft. It seems like most people believe there will
be one or more of these classes, but the spec doesn't say anything at
all about them. Unless we do something, our draft will imply that
there won't be these classes, but we will still be assuming there will
be.
The spec excludes these classes quite explicitly, in the CPL examples.
The class precedence lists include all the user-defined classes and T,
but nothing else. Also, the section on Meta Objects makes no mention
of "object" or "standard-object".
We could either make a decision on this, or include it in the spec under
a new section "Issues still under Discussion". It might happen that
other issues will have the same uncertain status at the November
deadline. Constructors are presently in that category as well.
∂14-Oct-87 0950 @Score.Stanford.EDU:kempf%hplabsz@hplabs.HP.COM Re: status of "object" or "standard-object"
Received: from SCORE.STANFORD.EDU by SAIL.STANFORD.EDU with TCP; 14 Oct 87 09:50:48 PDT
Received: from hplabs.HP.COM (hplabs.hpl.hp.com.#Internet) by SCORE.STANFORD.EDU with TCP; Wed 14 Oct 87 09:37:23-PDT
Received: from hplms2 by hplabs.HP.COM with SMTP ; Wed, 14 Oct 87 09:37:15 PDT
Received: from hplabsz.hpl.hp.com by hplms2; Wed, 14 Oct 87 12:36:56 edt
Return-Path: <kempf@hplabsz>
Received: from hplabsz by hplabsz; Wed, 14 Oct 87 09:36:15 pdt
To: "Sonya E. Keene" <skeene@STONY-BROOK.SCRC.Symbolics.COM>
Cc: common-lisp-object-system@sail.stanford.edu
Subject: Re: status of "object" or "standard-object"
X-Mailer: mh6.5
In-Reply-To: Your message of Wed, 14 Oct 87 11:27:00 -0400.
<871014112750.2.SKEENE@JUNCO.SCRC.Symbolics.COM>
Date: Wed, 14 Oct 87 09:36:12 MDT
Message-Id: <1519.561224172@hplabsz>
From: kempf%hplabsz@hplabs.HP.COM
> We could either make a decision on this, or include it in the spec under
> a new section "Issues still under Discussion". It might happen that
> other issues will have the same uncertain status at the November
> deadline. Constructors are presently in that category as well.
My feeling on this is that all references to subjects covered in Part 3
(metaobject protocol) should be qualified as still under discussion.
The qualification need not be local to the reference, but could be
global to Part 1. When we meet in November (or possibly via. e-mail
before) we can perhaps finalize, but to do otherwise would be unfair
to Dick and Linda.
jak
∂14-Oct-87 0950 @Score.Stanford.EDU:kempf%hplabsz@hplabs.HP.COM Re: Name Change for Metaobject Protocol?
Received: from SCORE.STANFORD.EDU by SAIL.STANFORD.EDU with TCP; 14 Oct 87 09:50:51 PDT
Received: from hplabs.HP.COM (hplabs.hpl.hp.com.#Internet) by SCORE.STANFORD.EDU with TCP; Wed 14 Oct 87 09:38:36-PDT
Received: from hplms2 by hplabs.HP.COM with SMTP ; Wed, 14 Oct 87 09:39:07 PDT
Received: from hplabsz.hpl.hp.com by hplms2; Wed, 14 Oct 87 12:38:49 edt
Return-Path: <kempf@hplabsz>
Received: from hplabsz by hplabsz; Wed, 14 Oct 87 09:38:07 pdt
To: Gregor.pa@Xerox.COM
Cc: kempf%hplabsz@hplabs.HP.COM, common-lisp-object-system@sail.stanford.edu
Subject: Re: Name Change for Metaobject Protocol?
X-Mailer: mh6.5
In-Reply-To: Your message of Tue, 13 Oct 87 10:21:00 -0700.
<871013102112.0.GREGOR@SPIFF.isl.parc.xerox.com>
Date: Wed, 14 Oct 87 09:38:03 MDT
Message-Id: <1709.561224283@hplabsz>
From: kempf%hplabsz@hplabs.HP.COM
> The objects in the meta-object protocol are the objects which implement
> the (metacircular) evaluator. So the current name is just right.
OK, let it be then.
Gregor, we'll all be thinking of you during your operation. Good luck!
jak
∂14-Oct-87 1026 @Score.Stanford.EDU:kempf%hplabsz@hplabs.HP.COM Re: Status (and TRACE-EXECUTION spec)
Received: from SCORE.STANFORD.EDU by SAIL.STANFORD.EDU with TCP; 14 Oct 87 10:25:57 PDT
Received: from hplabs.HP.COM (hplabs.hpl.hp.com.#Internet) by SCORE.STANFORD.EDU with TCP; Wed 14 Oct 87 10:00:40-PDT
Received: from hplms2 by hplabs.HP.COM with SMTP ; Wed, 14 Oct 87 10:01:48 PDT
Received: from hplabsz.hpl.hp.com by hplms2; Wed, 14 Oct 87 13:01:26 edt
Return-Path: <kempf@hplabsz>
Received: from hplabsz by hplabsz; Wed, 14 Oct 87 10:00:42 pdt
To: Dick Gabriel <RPG@SAIL.Stanford.EDU>
Cc: common-lisp-object-system@SAIL.Stanford.EDU
Subject: Re: Status (and TRACE-EXECUTION spec)
X-Mailer: mh6.5
In-Reply-To: Your message of 13 Oct 87 14:27:00 -0700.
Date: Wed, 14 Oct 87 10:00:36 MDT
Message-Id: <3026.561225636@hplabsz>
From: kempf%hplabsz@hplabs.HP.COM
>
> LGD and I are working (like mad) on the spec. I am concentrating
> on the concepts chapter and Linda on the functions chapter.
> This will require very fast turnaround from you folks on the draft.
Ok, let us know if you need anything else.
I haven't posted an updated draft of the TRACE-EXECUTION generic function
yet, since it wasn't clear from the last meeting whether it was in
the same category as PRINT-OBJECT, and therefore should go in Section 2,
or was a Cleanup Committee issue. Clearly, the modifications to TRACE
are a Cleanup Committee issue. In any event, below is the text of the
TRACE-EXECUTION generic function spec I presented at the September meeting,
in case it should go in Section 2.
jak
Uppercase indicates BOLD, _this_ indicates italic
-------------------------------------------------------------------------------
TRACE-EXECUTION _object_ &KEY :ENVIRONMENT :BREAK _[Generic Function]_
TRACE-EXECUTION discriminates on _object_ to select an implementation
specific method that arranges for the executable entity associated
with _object_ to be traced. The :ENVIRONMENT keyword parameter is for
those implementations which require environmental information to
arrange for tracing to occur. Implementations are required to provide
TRACE-EXECUTION as the system level entry point for implementing TRACE
functionality. If the :BREAK keyword argument is not NIL, arrangement is
made for the BREAK function to be called after trace information is printed.
The exact nature and number of methods associated with TRACE-EXECUTION
will differ, depending on what executable entities can be specified
by TRACE, but every implementation needs to support methods which
dispatch on objects having the following classes:
SYMBOL-The function indicated by the symbol will be traced when invoked
in the environment.
METHOD-The method function is traced when invoked.
GENERIC-FUNCTION-The generic function is traced when the discriminator
code is invoked.
Implementations are encouraged to provide as many methods as is possible.
∂14-Oct-87 1029 @Score.Stanford.EDU:kempf%hplabsz@hplabs.HP.COM Re: Constructors
Received: from SCORE.STANFORD.EDU by SAIL.STANFORD.EDU with TCP; 14 Oct 87 10:29:08 PDT
Received: from hplabs.HP.COM (hplabs.hpl.hp.com.#Internet) by SCORE.STANFORD.EDU with TCP; Wed 14 Oct 87 10:14:08-PDT
Received: from hplms2 by hplabs.HP.COM with SMTP ; Wed, 14 Oct 87 10:15:01 PDT
Received: from hplabsz.hpl.hp.com by hplms2; Wed, 14 Oct 87 13:14:44 edt
Return-Path: <kempf@hplabsz>
Received: from hplabsz by hplabsz; Wed, 14 Oct 87 10:14:03 pdt
To: dussud%jenner.csc.ti.com@csnet-relay.ARPA
Cc: Common-Lisp-Object-System@SAIL.STANFORD.EDU
Subject: Re: Constructors
X-Mailer: mh6.5
In-Reply-To: Your message of Mon, 12 Oct 87 14:09:38 -0500.
<2770052978-7072022@Jenner>
Date: Wed, 14 Oct 87 10:14:00 MDT
Message-Id: <3277.561226440@hplabsz>
From: kempf%hplabsz@hplabs.HP.COM
> In conclusion since I don't think the option is hard to understand or to
> explain and since any serious implementation will have to do something
> like that (at the sub-meta level at least), I think it is a good thing
> to standardize.
I pretty much agree with Danny and Gregor on this, and oppose adding
constructors. In addition, it is another DEFCLASS option, further
complicating the class creation language.
jak
∂14-Oct-87 1046 Moon@STONY-BROOK.SCRC.Symbolics.COM Re: fixing our problems with setf
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 14 Oct 87 10:46:35 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 255219; Wed 14-Oct-87 13:47:14 EDT
Date: Wed, 14 Oct 87 13:47 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: fixing our problems with setf
To: Pavel.pa@Xerox.COM
cc: Common-Lisp-Object-System@SAIL.STANFORD.EDU
In-Reply-To: <871013-200700-6060@Xerox>
Message-ID: <19871014174716.1.MOON@EUPHRATES.SCRC.Symbolics.COM>
Line-fold: No
Date: Tue, 13 Oct 87 20:01:00 PDT
From: Pavel.pa@Xerox.COM
A nit in your test case. It would be nicer if the optional variable end
had a default value rather than using the (unless end ...) hack:
Not so. Refer to the definition of the meaning of the arguments to functions
like subseq, CLtL p.246, which says that supplying NIL as end is the same as
omitting end.
;If setf of subseq was not already built into Common Lisp,
;it could have been defined like this
(defun (setf subseq) (new-value sequence start &optional (end (length
sequence)))
(setq end (min end (+ start (length new-value))))
(do ((i start (1+ i))
(j 0 (1+ j)))
((= i end) new-value)
(setf (elt sequence i) (elt new-value j))))
∂14-Oct-87 1620 DLW@ALDERAAN.SCRC.Symbolics.COM Name Change for Metaobject Protocol?
Received: from [128.81.41.109] by SAIL.STANFORD.EDU with TCP; 14 Oct 87 16:20:25 PDT
Received: from CHICOPEE.SCRC.Symbolics.COM by ALDERAAN.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 129525; Wed 14-Oct-87 17:19:30 EDT
Date: Wed, 14 Oct 87 17:18 EDT
From: Daniel L. Weinreb <DLW@ALDERAAN.SCRC.Symbolics.COM>
Subject: Name Change for Metaobject Protocol?
To: Gregor.pa@Xerox.COM, kempf%hplabsz@hplabs.HP.COM
cc: common-lisp-object-system@sail.stanford.edu
In-Reply-To: <871013102112.0.GREGOR@SPIFF.isl.parc.xerox.com>
Message-ID: <19871014211812.0.DLW@CHICOPEE.SCRC.Symbolics.COM>
Line-fold: No
The CLOS use of "meta-object" also seems right to me. I agree that
there would be some degree of confusion if we were presenting CLOS
primarily to an audience steeped in Smalltalk-80, which is what one
experiences at OOPSLA for the most part. But for the Lisp people, I
don't think the differences between our meta-objects and Smalltalk-80
metaclasses are a big enough problem to try to find some other
terminology.
∂16-Oct-87 0639 Moon@MEAD.SCRC.Symbolics.COM CLASS-CHANGED and UPDATE-OBSOLETE-INSTANCE
Received: from [128.81.41.234] by SAIL.STANFORD.EDU with TCP; 16 Oct 87 06:39:40 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by MEAD.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 97363; Thu 1-Oct-87 12:40:09 EDT
Date: Thu, 1 Oct 87 12:40 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: CLASS-CHANGED and UPDATE-OBSOLETE-INSTANCE
To: common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: <22064.560102555@hplabsz>
Message-ID: <871001124004.7.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Thu, 01 Oct 87 10:02:35 MST
From: kempf%hplabsz@hplabs.HP.COM
Aren't these generic functions essentially doing the same thing?
No, because CLASS-CHANGED inherently involves two classes, but
UPDATE-OBSOLETE-INSTANCE inherently involves one class. They used
to do, and be, the same thing, before we simplified class redefinition
a couple of weeks ago.
Recall that CLASS-CHANGED methods can take advantage of abstractions,
rather than knowing about slots. Abstraction seems particularly
important when more than one class is involved.
∂16-Oct-87 0659 Moon@MEAD.SCRC.Symbolics.COM CLASS-CHANGED and UPDATE-OBSOLETE-INSTANCE
Received: from [128.81.41.234] by SAIL.STANFORD.EDU with TCP; 16 Oct 87 06:39:40 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by MEAD.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 97363; Thu 1-Oct-87 12:40:09 EDT
Date: Thu, 1 Oct 87 12:40 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: CLASS-CHANGED and UPDATE-OBSOLETE-INSTANCE
To: common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: <22064.560102555@hplabsz>
Message-ID: <871001124004.7.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Thu, 01 Oct 87 10:02:35 MST
From: kempf%hplabsz@hplabs.HP.COM
Aren't these generic functions essentially doing the same thing?
No, because CLASS-CHANGED inherently involves two classes, but
UPDATE-OBSOLETE-INSTANCE inherently involves one class. They used
to do, and be, the same thing, before we simplified class redefinition
a couple of weeks ago.
Recall that CLASS-CHANGED methods can take advantage of abstractions,
rather than knowing about slots. Abstraction seems particularly
important when more than one class is involved.
∂17-Oct-87 1157 RPG Constructors
To: common-lisp-object-system@SAIL.Stanford.EDU
I favor Moon's proposal.
-rpg-
∂18-Oct-87 2151 RPG The Results are In!
To: common-lisp-object-system@SAIL.Stanford.EDU
Here is the vote on dynamic versus indefinite extent of CALL-NEXT-METHOD:
Person Vote
-------------------------
Pavel dynamic
Dussud abstain
Gregor indefinite
Danny indefinite
Moon abstain (leans towards indefinite)
Kempf dynamic
Masinter dynamic
LGD dynamic
rpg abstain (leans towards dynamic)
Mlynarik indefinite
I think dynamic wins. Wny not say that CLOS specifies dynamic but that
a valid extension is indefinite?
-rpg-
∂19-Oct-87 0806 @Score.Stanford.EDU:kempf%hplabsz@hplabs.HP.COM Re: The Results are In!
Received: from SCORE.STANFORD.EDU by SAIL.STANFORD.EDU with TCP; 19 Oct 87 08:05:57 PDT
Received: from hplabs.HP.COM (hplabs.hpl.hp.com.#Internet) by SCORE.STANFORD.EDU with TCP; Mon 19 Oct 87 07:48:26-PDT
Received: from hplms2 by hplabs.HP.COM with SMTP ; Mon, 19 Oct 87 07:49:35 PDT
Received: from hplabsz.hpl.hp.com by hplms2; Mon, 19 Oct 87 07:49:20 pdt
Return-Path: <kempf@hplabsz>
Received: from hplabsz by hplabsz; Mon, 19 Oct 87 08:48:54 pdt
To: Dick Gabriel <RPG@SAIL.Stanford.EDU>
Cc: common-lisp-object-system@SAIL.Stanford.EDU
Subject: Re: The Results are In!
X-Mailer: mh6.5
In-Reply-To: Your message of 18 Oct 87 21:51:00 -0700.
Date: Mon, 19 Oct 87 08:48:51 MDT
Message-Id: <28847.561653331@hplabsz>
From: kempf%hplabsz@hplabs.HP.COM
>
> I think dynamic wins. Wny not say that CLOS specifies dynamic but that
> a valid extension is indefinite?
fine.
jak
∂19-Oct-87 0900 Bobrow.pa@Xerox.COM initialize-instance on an exisiting instance
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 19 Oct 87 09:00:42 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 19 OCT 87 09:01:23 PDT
Date: 19 Oct 87 09:01 PDT
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: initialize-instance on an exisiting instance
To: common-lisp-object-system@SAIL.Stanford.EDU
cc: Bobrow.pa@Xerox.COM
Message-ID: <871019-090123-6051@Xerox>
We did not discuss this, but if a user calls
initialize-instance
on an existing instance, it seems that it should work. This would be a
way of reinitializing an instance. Is there any problem with this? I
would rather this be true than say "it is an error" to initialize an
instance more than once.
∂19-Oct-87 0932 Moon@YUKON.SCRC.Symbolics.COM initialize-instance on an exisiting instance
Received: from SCRC-YUKON.ARPA by SAIL.STANFORD.EDU with TCP; 19 Oct 87 09:32:13 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by YUKON.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 278640; Mon 19-Oct-87 12:33:18 EDT
Date: Mon, 19 Oct 87 12:33 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: initialize-instance on an exisiting instance
To: common-lisp-object-system@SAIL.Stanford.EDU
In-Reply-To: <871019-090123-6051@Xerox>
Message-ID: <19871019163310.6.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: 19 Oct 87 09:01 PDT
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
We did not discuss this, but if a user calls
initialize-instance
on an existing instance, it seems that it should work. This would be a
way of reinitializing an instance. Is there any problem with this? I
would rather this be true than say "it is an error" to initialize an
instance more than once.
Given what we said about permissible optimizations in initialize-instance, I
don't see how the semantics of this operation could be well-defined, unless
this isn't really the same initialize-instance that make-instance calls.
That might be reasonable: change "permissible optimizations in
initialize-instance" to "permissible optimizations in initialize-instance
when called by make-instance."
However, I'm not sure that calling initialize-instance on an existing
instance is going to be a particularly useful operation. Does it first
reset all the slots to uninitialized? Regular initialize-instance doesn't
do that. What if there are user-defined initialize-instance methods that
do such things as adding the instance to an auxiliary data structure? Can
they tolerate adding it twice? Or should one call a new function
deinitialize-instance before calling initialize-instance?
∂19-Oct-87 0951 Bobrow.pa@Xerox.COM Re: The Results are In!
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 19 Oct 87 09:51:06 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 19 OCT 87 09:51:47 PDT
Date: 19 Oct 87 09:51 PDT
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Re: The Results are In!
In-reply-to: Dick Gabriel <RPG@SAIL.Stanford.EDU>'s message of 18 Oct 87
21:51 PDT
To: RPG@SAIL.Stanford.EDU
cc: common-lisp-object-system@SAIL.Stanford.EDU
Message-ID: <871019-095147-6164@Xerox>
I think dynamic wins. Wny not say that CLOS specifies dynamic
but that a valid extension is indefinite?
Fine. I will bet that almost all implementations will be indefinite,
and users will get used to indefinite if it makes any difference. But I
think that dynamic will make a difference extremely rarely.
danny
∂19-Oct-87 1016 Bobrow.pa@Xerox.COM Re: initialize-instance on an exisiting instance
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 19 Oct 87 10:15:55 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 19 OCT 87 10:15:57 PDT
Date: 19 Oct 87 10:15 PDT
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Re: initialize-instance on an exisiting instance
In-reply-to: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>'s
message of Mon, 19 Oct 87 12:33 EDT
To: Moon@STONY-BROOK.SCRC.Symbolics.COM
cc: common-lisp-object-system@SAIL.Stanford.EDU
Message-ID: <871019-101557-6220@Xerox>
Date: 19 Oct 87 09:01 PDT From: Danny Bobrow
<Bobrow.pa@Xerox.COM>
We did not discuss this, but if a user calls
initialize-instance
on an existing instance, it seems that it should work.
This would be a way of reinitializing an instance. Is there
any problem with this? I would rather this be true than say
"it is an error" to initialize an instance more than once.
Given what we said about permissible optimizations in
initialize-instance, I don't see how the semantics of this
operation could be well-defined, unless this isn't really the same
initialize-instance that make-instance calls. That might be
reasonable: change "permissible optimizations in
initialize-instance" to "permissible optimizations in
initialize-instance when called by make-instance."
Either what I am asking makes sense, and it must be "permissible
optimizations in initialize-instance when called by make-instance.", or
what I am saying is nonsense, and the only place initialize-instance can
be called is make-instance, in which case "permissible optimizations in
initialize-instance" is the same as "permissible optimizations in
initialize-instance when called by make-instance."
However, I'm not sure that calling initialize-instance on an
existing instance is going to be a particularly useful operation.
Does it first reset all the slots to uninitialized? Regular
initialize-instance doesn't do that. What if there are
user-defined initialize-instance methods that do such things as
adding the instance to an auxiliary data structure? Can they
tolerate adding it twice? Or should one call a new function
deinitialize-instance before calling initialize-instance?
I think users who cause side effects in initialization should be aware
of them. But otherwise one would want the effect to be as though you
had just allocated a new instance, except that one has an instance eq to
the original. We have had some Loops users who have used a feature
like this. But the problems you mention are real, and it was why I sent
out my query.
Perhaps, a simpler way of providing for this purpose would be to provide
a generic-function (copy-slot-contents from to) whose default behavior
for instances of the same class is to copy the contents (incuding
unbound slots). Or should this be only a function that signals an error
when the classes of the two instances are not the same? Or is this too
esoteric an application to be included in the standard. In any event,
we must make a statement about initialize-instance, and how many times
it can be called (and from where?).
∂19-Oct-87 1826 Bobrow.pa@Xerox.COM Re: Constructors
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 19 Oct 87 18:26:13 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 19 OCT 87 18:18:13 PDT
Date: 19 Oct 87 18:18 PDT
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Re: Constructors
In-reply-to: Dick Gabriel <RPG@SAIL.Stanford.EDU>'s message of 17 Oct 87
11:57 PDT
To: common-lisp-object-system@SAIL.Stanford.EDU
Message-ID: <871019-181813-1026@Xerox>
If we are voting, I prefer leaving it out of the standard for now.
danny
∂20-Oct-87 0926 RPG Constructors
To: common-lisp-object-system@SAIL.Stanford.EDU
The argument I buy for having constructors is that they provide
a more abstract interface than make-instance. Using the Principle
of Insignificant Degradation and Occam's Chainsaw, I don't think that
make-instance and constructors burden the user with too many ways to
do things, given that one is an abstraction mechanism.
-rpg-
∂20-Oct-87 1028 Bobrow.pa@Xerox.COM Re: Constructors
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 20 Oct 87 10:28:31 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 20 OCT 87 10:28:25 PDT
Date: 20 Oct 87 10:28 PDT
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Re: Constructors
In-reply-to: Dick Gabriel <RPG@SAIL.Stanford.EDU>'s message of 20 Oct 87
09:26 PDT
To: RPG@SAIL.Stanford.EDU
cc: common-lisp-object-system@SAIL.Stanford.EDU
Message-ID: <871020-102825-1807@Xerox>
The argument I buy for having constructors is that they provide
a more abstract interface than make-instance. Using the Principle
of Insignificant Degradation and Occam's Chainsaw, I don't think
that make-instance and constructors burden the user with too many
ways to do things, given that one is an abstraction mechanism.
The abstract interfaces are functions that the user can write, with very
few extra characters. Occam's chainsaw cuts off extra mechanism when it
serves no real purpose. The extra syntax in defclass, the functions to
make constructors, etc are all extra baggage
One compares:
(defclass foo ()
(a b)
(:constructor make-foo))
with
(defclass foo ()
(a b))
(defun make-foo (initargs)
(make-instance 'foo initargs))
And then if the user decides to have make-foo do some additonal work,
there is appropriate place to put the code.
∂20-Oct-87 1033 skeene@STONY-BROOK.SCRC.Symbolics.COM Constructors
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 20 Oct 87 10:33:10 PDT
Received: from JUNCO.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 259181; Tue 20-Oct-87 13:34:06 EDT
Date: Tue, 20 Oct 87 13:34 EDT
From: Sonya E. Keene <skeene@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Constructors
To: RPG@SAIL.STANFORD.EDU
cc: common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: The message of 20 Oct 87 12:26 EDT from Dick Gabriel <RPG@SAIL.Stanford.EDU>
Message-ID: <19871020173404.8.SKEENE@JUNCO.SCRC.Symbolics.COM>
Date: 20 Oct 87 0926 PDT
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>
The argument I buy for having constructors is that they provide
a more abstract interface than make-instance.
This argument appeals to me as well. I vote in favor of constructors.
∂20-Oct-87 1923 Pavel.pa@Xerox.COM The extent of CALL-NEXT-METHOD (a retraction)
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 20 Oct 87 19:23:07 PDT
Received: from Semillon.ms by ArpaGateway.ms ; 20 OCT 87 19:23:50 PDT
Date: Tue, 20 Oct 87 19:23:36 PDT
From: Pavel.pa@Xerox.COM
Subject: The extent of CALL-NEXT-METHOD (a retraction)
To: Common-Lisp-Object-System@SAIL.Stanford.Edu
Message-ID: <871020-192350-2853@Xerox>
Well, I had a conversation with Danny about this issue. He brought up
the following example, which I find compelling enough to justify
switching my ``vote'' from `dynamic' to `indefinite'.
Suppose we pick the `dynamic' extent. Suppose that you've got a piece
of code in some method that includes an FLET'd function and suppose
further the method returns said function as its value. This is fine, it
should work, we've all probably done something like it a dozen times.
However, if you've got a call to CALL-NEXT-METHOD inside that FLET'd
function, then it doesn't work, something awful happens, we'll all get
bit by it a dozen times and curse our short-sightedness.
I can't off-hand come up with an example of something else in Common
Lisp that I have to be careful of, except for things that I already find
it intuitive to worry about: special variables, condition handlers,
CATCH phrases, etc. The function CALL-NEXT-METHOD is not obviously
`dynamic'; I therefore predict that I (and many other programmers) will
fail to remember that it IS `dynamic' and that we will therefore make
such mistakes many times before we learn.
It is, of course, no consolation that many (most? probably not all)
implementations will, in fact, allow indefinite extent. That simply
means that I won't realize my mistake until I'm porting my code to the
one implementation that met the spec exactly.
So, as I said above, consider this a change of my ``vote''.
Pavel
∂21-Oct-87 0835 @Score.Stanford.EDU:kempf%hplabsz@hplabs.HP.COM Re: The extent of CALL-NEXT-METHOD (a retraction)
Received: from SCORE.STANFORD.EDU by SAIL.STANFORD.EDU with TCP; 21 Oct 87 08:34:58 PDT
Received: from hplabs.HP.COM (hplabs.hpl.hp.com.#Internet) by SCORE.STANFORD.EDU with TCP; Wed 21 Oct 87 08:33:24-PDT
Received: from hplms2 by hplabs.HP.COM with SMTP ; Wed, 21 Oct 87 08:33:38 PDT
Received: from hplabsz.hpl.hp.com by hplms2; Wed, 21 Oct 87 08:33:15 pdt
Return-Path: <kempf@hplabsz>
Received: from hplabsz by hplabsz; Wed, 21 Oct 87 09:32:48 pdt
To: Pavel.pa@Xerox.COM
Cc: Common-Lisp-Object-System@SAIL.Stanford.Edu
Subject: Re: The extent of CALL-NEXT-METHOD (a retraction)
X-Mailer: mh6.5
In-Reply-To: Your message of Tue, 20 Oct 87 19:23:36 -0700.
<871020-192350-2853@Xerox>
Date: Wed, 21 Oct 87 08:32:45 PDT
Message-Id: <23704.561828765@hplabsz>
From: kempf%hplabsz@hplabs.HP.COM
> Suppose we pick the `dynamic' extent. Suppose that you've got a piece
> of code in some method that includes an FLET'd function and suppose
> further the method returns said function as its value. This is fine, it
> should work, we've all probably done something like it a dozen times.
> However, if you've got a call to CALL-NEXT-METHOD inside that FLET'd
> function, then it doesn't work, something awful happens, we'll all get
> bit by it a dozen times and curse our short-sightedness.
I didn't buy this argument when I first heard it, and I don't buy it
now.
FLET and CALL-NEXT-METHOD are two different things. The definition of
a locally defined function must be lexically visible inside the definition
of FLET. That is, after all, the function of FLET. Thus, if the lexically
defined function is thrown out of the scope of the FLET, arrangement for
calculation of a closure over the lexical environment can be made at compile
time. The definition of CALL-NEXT-METHOD, on the other hand, is not lexically
precisely determined at all. Within a particular lexical scope,
CALL-NEXT-METHOD is defined to call the "next" method. Precisely what the
"next" method is will be determined by the parameters of the generic
function invocation, during the effective method calculation. In general,
these can only be determined at run time, thus the definition of
CALL-NEXT-METHOD is determined dynamically, and the compiler cannot form a
closure if the CALL-NEXT-METHOD leaks out of scope. In specific instances
it may be possible to optimize out the run time calculation, but that
should not be of concern in specifying CALL-NEXT-METHOD does.
So, for CALL-NEXT-METHOD to become indefinite in extent, Common Lisp needs the
addition of dynamic closures. Other languages (and some extensions of
Common Lisp) have these-they're called "coroutines" or "lightweight processes".
These take a closure over varying aspects of the dynamic state of the
program. In the case of CALL-NEXT-METHOD, the amount of state which would
need to be saved may not be as much as in the case of a coroutine, but
the principle is the same.
Since this would be the only case of taking a dynamic closure in Common
Lisp, I think we should stick with dynamic extent.
jak
∂21-Oct-87 0848 @Score.Stanford.EDU:kempf%hplabsz@hplabs.HP.COM Re: Constructors
Received: from SCORE.STANFORD.EDU by SAIL.STANFORD.EDU with TCP; 21 Oct 87 08:47:56 PDT
Received: from hplabs.HP.COM (hplabs.hpl.hp.com.#Internet) by SCORE.STANFORD.EDU with TCP; Wed 21 Oct 87 08:46:48-PDT
Received: from hplms2 by hplabs.HP.COM with SMTP ; Wed, 21 Oct 87 08:45:48 PDT
Received: from hplabsz.hpl.hp.com by hplms2; Wed, 21 Oct 87 08:45:27 pdt
Return-Path: <kempf@hplabsz>
Received: from hplabsz by hplabsz; Wed, 21 Oct 87 09:44:58 pdt
To: Dick Gabriel <RPG@SAIL.Stanford.EDU>
Cc: common-lisp-object-system@SAIL.Stanford.EDU
Subject: Re: Constructors
X-Mailer: mh6.5
In-Reply-To: Your message of 20 Oct 87 09:26:00 -0700.
Date: Wed, 21 Oct 87 08:44:55 PDT
Message-Id: <23800.561829495@hplabsz>
From: kempf%hplabsz@hplabs.HP.COM
> The argument I buy for having constructors is that they provide
> a more abstract interface than make-instance. Using the Principle
> of Insignificant Degradation and Occam's Chainsaw, I don't think that
> make-instance and constructors burden the user with too many ways to
> do things, given that one is an abstraction mechanism.
I don't think the difference between;
(make-foo :name 'bar :number-of-widgits 50)
and:
(make-instance 'foo :name 'bar :number-of-widgits 50)
is sufficiently large to constitute a useful addition in abstraction.
Most programmers will want to name their constructors in a way which
is reflective of their function, to construct a particular class. Thus,
if they change the class name, it would make sense to change the
constructor name, so that the name continues to reflect the function.
Whether they change a constructor function name or a class name in
a MAKE-INSTANCE form makes little difference. Thus, for the price of
yet another DEFCLASS construct, you get very little in the way of
additional abstraction. And, as has been argued, programmers who
want to do this will do it anyway. Most programmers are going to
want to do things like:
(defun make-bar-foo (widgits)
(make-instance 'foo :name 'bar :number-of-widgits widgits))
and constructors won't help there. Or, if they could, the addition to
the DEFCLASS syntax wouldn't be worth the savings in not having to define
the constructor seperately.
The only argument I find vaguely attractive is the optimization one,
though I suspect this is probably more of an issue on dedicated hardware
than on general purpose machines. However, since the general Common Lisp
method of specifying optimizations is using the DECLARE construct, I
think any attempt to optimize instance construction should go that route.
I therefore vote "NO" on Measure C.
jak
∂21-Oct-87 0956 Moon@STONY-BROOK.SCRC.Symbolics.COM indefinite extent of call-next-method
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 21 Oct 87 09:56:26 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 260036; Wed 21-Oct-87 12:57:27 EDT
Date: Wed, 21 Oct 87 12:57 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: indefinite extent of call-next-method
To: Common-Lisp-Object-System@sail.stanford.edu
References: <871020-192350-2853@Xerox>,<23704.561828765@hplabsz>
Message-ID: <19871021165723.1.MOON@EUPHRATES.SCRC.Symbolics.COM>
Pavel is right, of course.
I don't find Jim's argument convincing at all. To my mind,
call-next-method is a function that is closed over the identity
of the next method and the arguments to be passed to it, just
as a function defined by labels with a free reference that is
captured in an outer scope is closed over the variable in the
free reference. In both cases it's equally true and equally
irrelevant to the scope of the closure that the value of the
closed-over variable is only known at run time.
∂21-Oct-87 1000 @Score.Stanford.EDU:kempf%hplabsz@hplabs.HP.COM TRACE Proposal
Received: from SCORE.STANFORD.EDU by SAIL.STANFORD.EDU with TCP; 21 Oct 87 10:00:21 PDT
Received: from hplabs.HP.COM (hplabs.hpl.hp.com.#Internet) by SCORE.STANFORD.EDU with TCP; Wed 21 Oct 87 09:58:54-PDT
Received: from hplms2 by hplabs.HP.COM with SMTP ; Wed, 21 Oct 87 09:59:19 PDT
Received: from hplabsz.hpl.hp.com by hplms2; Wed, 21 Oct 87 09:58:43 pdt
Return-Path: <kempf@hplabsz>
Received: from hplabsz by hplabsz; Wed, 21 Oct 87 10:58:12 pdt
To: Masinter.pa@Xerox.com
Cc: Common-Lisp-Object-System@sail.stanford.edu
Subject: TRACE Proposal
X-Mailer: mh6.5
Date: Wed, 21 Oct 87 09:58:09 PDT
Message-Id: <24566.561833889@hplabsz>
From: kempf%hplabsz@hplabs.HP.COM
Larry:
Here is a copy of the proposed modifications to TRACE, which
were discussed at the September CLOS committee meeting. I have not
included the TRACE-EXECUTION proposal, since it is a generic function,
similar to PRINT-OBJECT, and its disposition was not clear at the
meeting.
I hope this gets to you in time for the November meeting. If
not, apologies: OOPSLA and recovery took longer than expected.
Jim Kempf
-------------------------------------------------------------------------------
Issue: TRACE-CLOS
References: trace macro pp. 440-441
Category: MODIFICATION
Edit history: Version 1, 21-Oct-87 Kempf
Problem description:
With the addition of the Common Lisp Object System, there is no
command language level way to trace individual method execution.
The TRACE macro, as currently specified in Common Lisp, allows
only tracing of globally defined functions through their names.
Since a generic function name may have several executable methods,
users need some way to specify that they would like invocation of particular
methods to be traced, rather than invocation of the entire generic
function.
In addition, the current specification of TRACE does not allow tracing
of functions associated with SETF "methods", of macro functions,
nor of lexically defined functions or functions invoked via. their
function definition objects. While this proposal does not attempt
to address the latter problems, since identification and/or tracing of these
is likely to be implementation dependent, it does leave
open the option for those implementations which can arrange it. Finally,
some implementations of Common Lisp have extended TRACE to take an option
which puts the system into a break loop after the trace information has been
printed. This proposal adds that capability to the standard.
Proposal (TRACE-CLOS::TRACE-FUNCTION-SPECIFICATION)
(Font Note: UPPERCASE indicates bold, _this_ indicates italic)
TRACE _function-spec_ &KEY (:BREAK NIL) _[Macro]_
TRACE
UNTRACE _function-spec_ _[Macro]_
UNTRACE
Invoking TRACE with a function specification causes the function specified
to be traced. Henceforth, whenever the specified function is invoked,
information about the call, the arguments passed, and the returned
values, if any, will be printed to the stream that is the value of
*TRACE-OUTPUT*. If the keyword argument :BREAK is T, then the BREAK
function will be called after the trace information is printed.
UNTRACE undoes any tracing. Calling TRACE without any arguments
prints a list of currently traced executable entities, calling
UNTRACE without any arguments causes tracing to be undone for
all currently traced entities.
A _function_spec_ is either a symbol naming a function (i.e. a
symbol whose global function cell is bound to a function definition
object, or to which the application of MACRO-FUNCTION will return
a function definition object) or a list whose first element indicates
what kind of funcallable object is to be traced and whose tail indicates
which particular function should be traced. The complete set of
function specifications will necessarily be implementation dependent; however,
every implementation is required to support the following:
_symbol_-Invocations of the function or macrofunction named by
_symbol_ via. _symbol_ as a global name are traced.
(METHOD _generic-function-name-specification_
_{method-qualifiers}_*
_parameter-specializer-name-list_
)
If the method whose parameter specializer list, generic function
name specification, and method qualifiers are listed is tracable,
then invocations through the generic function name specification
will be traced.
(SETF _symbol_)-If the SETF function having the name specification
is tracable, it will be traced (see proposal SETF-CLOS for
more information on SETF name specifications).
Implementations are encouraged to provide for tracing of as many
funcallable objects as possible.
Rationale:
Adoption of the Common Lisp Object System will require the availability
of debugging information on individual methods.
Current practice:
Some Common Lisp implementations have extended TRACE syntax to
allow specification of breaks. Currently, the TRACE macro is
specified to take any number of symbols.
Adoption Cost:
The syntax of the TRACE macro will take only one function specification
in order to accomodate the :BREAK key. But, since TRACE tends to
be used interactively at the command langauge level, the impact
on existing code should be slight.
Cost of non-adoption:
Without this, implementation dependent ways of specifying the
:BREAK option would continue to be used. In addition, most
implementors would probably add their own syntax for allowing
programmers to obtain information on individual method invocation.
Benefits:
Allow programmers to obtain information on individual method
invocations.
Conversion Cost:
Minor re-write of the TRACE and UNTRACE macros.
∂21-Oct-87 1032 RPG The Latest Draft
To: common-lisp-object-system@SAIL.Stanford.EDU
The latest drafts for chapters 1, 2, and 3 are to be found in the files
concep.tex
functi.tex
mopfun.tex
on [cls,lsp]. The file tex.ins tells how to TEX these files.
Moon, Sonya, Danny, and Gregor are currently proofreading the drafts,
and LGD and I will spend most of our cycles servicing their comments,
but you should feel free to read them and comment.
-rpg-
∂21-Oct-87 1114 Gregor.pa@Xerox.COM indefinite extent of call-next-method
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 21 Oct 87 11:14:16 PDT
Received: from Semillon.ms by ArpaGateway.ms ; 21 OCT 87 11:12:29 PDT
Date: Wed, 21 Oct 87 11:12 PDT
From: Gregor.pa@Xerox.COM
Subject: indefinite extent of call-next-method
To: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
cc: Common-Lisp-Object-System@sail.stanford.edu
In-Reply-To: <19871021165723.1.MOON@EUPHRATES.SCRC.Symbolics.COM>
Message-ID: <871021111207.2.GREGOR@SPIFF.isl.parc.xerox.com>
Line-fold: no
Moreover, as I have tried to say before, I am pretty sure that people
reading the how method combination works stuff would naturally assume
indefinite extent since the behavior described there inherently is what
Moon described as:
Date: Wed, 21 Oct 87 12:57 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
To my mind,
call-next-method is a function that is closed over the identity
of the next method and the arguments to be passed to it, just
as a function defined by labels with a free reference that is
captured in an outer scope is closed over the variable in the
free reference. In both cases it's equally true and equally
irrelevant to the scope of the closure that the value of the
closed-over variable is only known at run time.
-------
∂21-Oct-87 1254 @RELAY.CS.NET:DUSSUD@jenner.csc.ti.com Re: Constructors
Received: from RELAY.CS.NET by SAIL.STANFORD.EDU with TCP; 21 Oct 87 12:54:22 PDT
Received: from relay2.cs.net by RELAY.CS.NET id ab17113; 21 Oct 87 15:34 EDT
Received: from csl.ti.com by RELAY.CS.NET id ad22000; 21 Oct 87 15:31 EDT
Received: from Jenner by tilde id AA07478; Wed, 21 Oct 87 13:53:45 CDT
Message-Id: <2770829823-15823760@Jenner>
Date: Wed, 21 Oct 87 13:57:03 CDT
From: Patrick H Dussud <DUSSUD%jenner.csc.ti.com@RELAY.CS.NET>
To: kempf%hplabsz@hplabs.hp.com
Cc: common-lisp-object-system@SAIL.STANFORD.EDU
Subject: Re: Constructors
In-Reply-To: Msg of Wed, 21 Oct 87 08:44:55 PDT from kempf%hplabsz@hplabs.hp.com
I don't think the difference between;
(make-foo :name 'bar :number-of-widgits 50)
and:
(make-instance 'foo :name 'bar :number-of-widgits 50)
is sufficiently large to constitute a useful addition in
abstraction.
The difference is the same as between
(send object :do-this ) and (do-this object).
Most programmers will want to name their constructors in a way which
is reflective of their function, to construct a particular class. Thus,
if they change the class name, it would make sense to change the
constructor name, so that the name continues to reflect the function.
Whether they change a constructor function name or a class name in
a MAKE-INSTANCE form makes little difference. Thus, for the price of
yet another DEFCLASS construct, you get very little in the way of
additional abstraction. And, as has been argued, programmers who
want to do this will do it anyway. Most programmers are going to
want to do things like:
(defun make-bar-foo (widgits)
(make-instance 'foo :name 'bar :number-of-widgits widgits))
You do that by adding the following option in the defclass:
(:CONSTRUCTOR make-bar-foo (number-of-widgits &aux (name 'bar)))
This option is textually close to the initargs declaration, which is
another advantage over a separate constructor function.
and constructors won't help there. Or, if they could, the addition to
the DEFCLASS syntax wouldn't be worth the savings in not having to define
the constructor seperately.
The only argument I find vaguely attractive is the optimization one,
though I suspect this is probably more of an issue on dedicated hardware
than on general purpose machines. However, since the general Common Lisp
method of specifying optimizations is using the DECLARE construct, I
think any attempt to optimize instance construction should go that route.
I don't think that the value of the constructor option as an aid to
optimization has anything to with the architecture of the machine. On
any architecture, if you implement MAKE-INSTANCE by interpreting the
various data structures (initargs list, default initargs), it is going
to be costly. You will need a mechanism to generate some specialized
code reflecting the interpretation for a particular class. If we don't
standardize the mechanism, every implementation will do it its own way,
including the programmer tinkering with metaclasses. I is better to
agree one a general mechanism. That's what the second part of Moon's
proposal is all about.
And I reiterate my "YES".
Patrick.
∂21-Oct-87 1649 Bobrow.pa@Xerox.COM Re: Constructors
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 21 Oct 87 16:49:22 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 21 OCT 87 16:44:26 PDT
Date: 21 Oct 87 16:39 PDT
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Re: Constructors
In-reply-to: Patrick H Dussud <DUSSUD%jenner.csc.ti.com@RELAY.CS.NET>'s
message of Wed, 21 Oct 87 13:57:03 CDT
To: DUSSUD%jenner.csc.ti.com@RELAY.CS.NET
cc: kempf%hplabsz@hplabs.hp.com,
common-lisp-object-system@SAIL.STANFORD.EDU
Message-ID: <871021-164426-4161@Xerox>
jak: I don't think the difference between;
(make-foo :name 'bar :number-of-widgits 50)
and:
(make-instance 'foo :name 'bar :number-of-widgits 50)
is sufficiently large to constitute a useful addition in
abstraction.
pd The difference is the same as between
(send object :do-this ) and (do-this object).
I don't understand the analogy at all.
pd You do that by adding the following option in the defclass:
(:CONSTRUCTOR make-bar-foo (number-of-widgits &aux (name 'bar)))
This option is textually close to the initargs declaration,
which is another advantage over a separate constructor function.
1) How does the &aux get added to the argument list of a constructor?
How does this do what jak asked for?
2) This option is not textually close to any inherited initarg
declarations. The fact that it is close to some and not all has large
confusion potential.
On any architecture, if you implement MAKE-INSTANCE by
interpreting the various data structures (initargs list, default
initargs), it is going to be costly. You will need a mechanism to
generate some specialized code reflecting the interpretation for a
particular class.
This is clearly a good thing.
The question it is better to focus it on calls to make-instance, or is
it better to combine this optimization with an automatic function
generation facility, with other features? The former seems like the
"general mechanism" to me (pd says "I think it is better to
agree one a general mechanism.")
∂21-Oct-87 2033 @STONY-BROOK.SCRC.Symbolics.COM,@EUPHRATES.SCRC.Symbolics.COM:Moon@STONY-BROOK.SCRC.Symbolics.COM First round of comments on the draft document
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 21 Oct 87 20:33:27 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via INTERNET with SMTP id 260598; 21 Oct 87 23:34:23 EDT
Date: Wed, 21 Oct 87 23:34 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: First round of comments on the draft document
To: Common-Lisp-Object-System@sail.stanford.edu
Message-ID: <19871022033419.0.MOON@EUPHRATES.SCRC.Symbolics.COM>
Comments on the 20 Oct 1987 16:34 draft of the CLOS documentation
pages 1-1 through 1-32.
I don't think we need the concept of "setf generic function" at all
any more. Such generic functions are now completely the same as
ordinary generic functions except that you get to them through
SYMBOL-FUNCTION of a name that is a list. I don't think we need
special mention of "setf generic functions" all over the place.
I would just say in the paragraph on 1-21 that begins "In Common
Lisp, a name can be given to a function...", something like
the following: "The name of a generic function, like the name of
an ordinary function, can be either a symbol or a two-element
list whose first element is {\bf setf} and whose second element
is a symbol. This is true for both local and global names."
The section "Introduction to Setf Generic Functions" can be completely
eliminated. If we want to publicize the recent cleanup that introduced
setf functions, we can attach that as an appendix; in any case, I think
this is better explained without reference to generic functions.
1-8 bottom of page: change two references to "setf method" to
"a method for writing the value of the slot", and then after
"appropriate generic functions" say the reading generic function
has a name specified in the defclass, while the writing generic
function is named (setf -reader-).
1-25 second paragraph: We don't need to make any distinction about
setf generic functions here; delete the paragraph.
================
The section title "Changing Classes" is poor. We aren't doing
anything to a class, we're doing something to an instance. A
more appropriate title would be "Changing the Class of an Instance".
================
We need to put in the glossary.
================
1-3 sixth paragraph: "ordered set" should be "list" in two places,
to avoid implying that duplicates are eliminated from the "set" of
parameter specializers or the "set" of qualifiers.
1-23 first paragraph under Introduction to Methods: same comment.
================
1-6 fourth paragraph: Clarify the range of n in the definition of
"superclass". I think you mean n >= 2, so that any "direct superclass"
is also a "superclass", but a class is not a superclass of itself.
================
1-8 bottom of page: "When a reader or accessor is specified for an
individual slot...": I don't understand what "individual" is in contrast to.
Every reader or accessor is for one slot, we don't have anything that
reads several slots and returns multiple values or anything like that.
If this sentence is just left over from the removal of :accessor-prefix,
we can just delete the sentence.
================
1-11 third bullet: we could just say "... union of the initialization
arguments declared in :initarg slot options in all the slot specifiers."
since all these bullets assume a set of slot specifiers for one name.
================
1-11 last sentence: needs to be updated with a correction I sent earlier,
because :default-initargs can appear more than once in a defclass.
================
1-15 last paragraph: It might be worth mentioning that the copy has dynamic
extent. This is mentioned in the remarks on 2-13, but it might be worth
repeating here.
================
1-16 fourth paragraph last sentence: "It is not allowed" is not defined
in the error terminology section. I think you mean "CLOS may be
extended to cover make-instance of a standard-type class or inclusion of
a standard type class as a superclass of a class."
================
1-18 last sentence: Actually a loop can contain more than two classes.
================
1-19 third paragraph last sentence: "will be followed by all classes
in T1", append "except t". The example could actually be generalized
to a join class J that isn't t, provided none of J's superclasses
appear elsewhere in the graph than above J. Then we have T1 up to
but not including J, followed by T2, ending in J and its superclasses.
================
1-23 last bullet: "(EQL -object-)" should be "(EQL -form-)", because
in a parameter specializer name, we have a form that is to be evaluated
to produce the object that appears in the parameter specializer. The
paragraph immediately following is wrong where it says "otherwise N
equals P" for this reason. We changed this when we changed QUOTE to EQL.
1-23 fourth paragraph: We no longer require parameter specializer names
to be Common Lisp type specifiers. (EQL -form-) is not a type-specifier.
================
1-23 last paragraph: I think the reference to make-instance here should
be changed to say specifically "make-instance of standard-method".
================
1-24 last paragraph: It's no longer true in the short form of
define-method-combination that primary methods can be unqualified.
Now, primary methods are qualified with the name of the type of
method combination, while auxiliary methods are qualified with :around.
================
1-32 first sentence: generic-flet, generic-labels, and with-added-methods
also accept a :method-combination argument.
================
1-32 first bullet last sentence: I don't understand why the word "only"
is present here. Maybe you mean "is supported only in :around methods
when a built-in" rather than "is supported in :around methods only when
a built-in"; i.e. does "only" modify ":around methods" or does it modify
"when"? Also, this sentence should probably be pulled out of the bullet
since I think it is saying something about both method roles. Maybe the
sentence should be deleted since the same information is repeated later
on the page.
================
OPEN ISSUES:
1-13 fourth paragraph: I think slot reinitialization should not be done
by a method for update-instance-structure. Instead it should be done at
the meta-object level, and defined to be completed before
update-instance-structure is called. This would be consistent with
change-class.
1-16 second paragraph: The specification about type-of here only applies
to instances of standard classes, or something like that. It certainly
doesn't apply to instances of all standard type classes. (Boy the
distinction between "standard class" and "standard type class" is
confusing! The two names always sound the same to me.)
1-17 I still think it's wrong for list to be more specific than symbol
in the CPL of null. Consider the print-object methods. Also consider
the introjection of symbol between list and sequence, a surprising CPL.
================
TYPOS:
1-7 bottom of page: "the generic function uninitialized-slot" should be
"the generic function slot-unbound".
1-9 last sentence: "invokes the function slot-value is to", "is" is
a typo.
1-15 third sentence: "When an instance is updated", "updated" should be
"changed".
1-15 fifth paragraph: Delete the whole paragraph, this was accidentally
copied from the "redefining classes" section.
1-19: "(food t)" should be "(food, t)" in two places. 1-20 also.
1-22 third paragraph: "defintions"
1-22: "a names of the form (setf name)"
1-22: "Consider setf form (setf ..." should be "Consider the form (setf ...".
1-23 first line: We haven't defined the term "setf macro". Could say
"a setf macro defined for name with defsetf or define-setf-method".
1-23 in the funcall: "#:temp-2" should be "#:temp-1".
1-25 bullet 4 last sentence: "in in" should be "in".
1-25 Section "Named Arguments...": In this section's title and text,
"named argument" should be "keyword argument". My fault: I forgot to
mail out a corrected version of this section when the terminology
was changed back.
∂22-Oct-87 0837 skeene@STONY-BROOK.SCRC.Symbolics.COM My comments on Chapter 1
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 22 Oct 87 08:37:41 PDT
Received: from JUNCO.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 260872; Thu 22-Oct-87 11:38:42 EDT
Date: Thu, 22 Oct 87 11:36 EDT
From: Sonya E. Keene <skeene@STONY-BROOK.SCRC.Symbolics.COM>
Subject: My comments on Chapter 1
To: rpg@SAIL.STANFORD.EDU
cc: common-lisp-object-system@SAIL.STANFORD.EDU
Message-ID: <19871022153612.9.SKEENE@JUNCO.SCRC.Symbolics.COM>
In general, the spec seems to be coming together nicely. I think it
reads better than it used to, and the tone is quite consistent
throughout.
----------------
I found it somewhat distracting that hyphenated functions are split
across lines.
1-7, second group of bullets, bullet #2:
"appropriately named" should be deleted; it implies that there is a
heuristic that makes up an appropriate name for the accessor generic
functions.
1-7, second to last paragraph
Fix typo "unitialized". Actually, I suggest deleting the sentence
containing the typo. The sentence is: "When an uninitialized slot is
read, the generic function uninitialized-slot is invoked." That's too
much detail for the overview; it bypasses describing the default
behavior, which would be more appropriate for an overview. In any
case, I believe the previous sentence is sufficient.
1-10, second paragraph under "Inheritance of Slots and Slot Options"
The last clause says "all instances of C access that single slot"; I
suggest saying instead "all instances of C can access that single slot"
or "that single slot is accessible to all instances of C."
1-13, regarding the default method for update-instance-structure
I like Moon's suggestion that the default method doesn't do the work.
But if that suggestion is not accepted, we should mention that users
should write after-methods unless they want to prevent the default
method from occurring. This could go at the end of the fourth
paragraph. Also it would be better to move the sentence beginning
"Methods for update-instance-structure can be defined..." from the 3rd
paragraph to the 4th, where the rest of the discussion about writing
methods is.
1-15
I agree with Moon that a better name is "Changing the Class of an
Instance". I also think it's confusing to use the terminology "old
class" and "new class" here, because the terms are used very differently
in the previous section. In the previous section "old class" meant
"that class that is now obsolete". Here it means "the previous class
of the instance". Here the "old class" is still current; it isn't
obsolete. I think new terminology could make it more clear what the
difference is between "changing the class of an instance" and
"redefining a class" -- how about using C-1 and C-2 terminology. That
makes it more clear that C-1 is not "old" or "obsolete" in any way; it's
just a class like any other.
Last paragraph: add "The default primary method for class-changed does
nothing." near the end of the paragraph.
1-17, Figure 1-1
The column header "Superclasses" doesn't make it clear that the order of
these classes is from most to least specific. In my draft of this the
column header was "Class Precedence List", which did make this clear.
1-19, First Example
Should state explicitly that the goal is to determine the CPL for the
class pie.
1-21, 3rd paragraph
"Ordinary functions and generic functions are called with identical
syntax." I can't remember for sure, but I believe we decided that
generic functions must have at least one required argument. If so,
this is one (minor) syntactic difference between ordinary and generic
functions.
1-21, 4th paragraph
Last sentence implies you need to evaluate a set of forms (a set of
defmethods and possibly a defgeneric) to produce a generic function
object, whereas really the evaluation of only one such form would do it.
1-21, last sentence
What is meant by "defgeneric (etc) are said to define a generic
function"? Unless you define "define", this is too vague to mean
anything. And if "define" means "create a g-f object", then defmethod
ought to be mentioned too.
1-22, second paragraph, last sentence
Regarding exporting names of generic functions from packages, the clause
"if it is part of an external interface" implies there is a way to
actually specify an external interface. I suggest replacing that
phrase with "if desired".
1-22, fifth paragraph, last sentence
I suggest replacing "The lambda-list of the generic function is defined
to be congruent with the lambda-list of the new method." with "The
lambda-list of the generic function is derived from the lambda-list of
the new method"
1-22, second to last paragraph
Typo: "specifying a names of"
1-25, second to last paragraph
"it is rare to find a vector used as a qualifier" -- The tone of this
clause is inconsistent with the usual factual, dry tone of the spec.
Since it doesn't add anything to what was already said, we should delete
it.
1-26, last paragraph
Change "not by all methods" to "not by all methods for the generic
function".
1-29, last paragrpah
Split up this too-long sentence into two or more sentences.
1-30, Standard Method Combination
I think the standard method combination should have a name, such as
"standard-method-combination". That name should be able to be given
to the :method-combination option to defgeneric, etc. It should be
noted as one of the Built-in Method Combination types. Just because it
is the default doesn't mean that it shouldn't have a name.
1-31
We don't say here what happens if a generic function is called and
there is no applicable method at all. Presumably an error is signaled.
1-32, first bullet, last sentence
Replace this sentence with "Use of the function call-next-method is
supported in :around methods."
1-32, second bullet
Add this sentence "Use of the function call-next-method is not
supported in primary methods."
1-32, third paragraph (excluding bullets)
It looks weird to have the close paren alone on the line. Bad line
break.
∂22-Oct-87 0842 @Score.Stanford.EDU:kempf%hplabsz@hplabs.HP.COM Re: indefinite extent of call-next-method
Received: from SCORE.STANFORD.EDU by SAIL.STANFORD.EDU with TCP; 22 Oct 87 08:42:05 PDT
Received: from hplabs.HP.COM (hplabs.hpl.hp.com.#Internet) by SCORE.STANFORD.EDU with TCP; Thu 22 Oct 87 08:40:52-PDT
Received: from hplms2 by hplabs.HP.COM with SMTP ; Thu, 22 Oct 87 08:42:21 PDT
Received: from hplabsz.hpl.hp.com by hplms2; Thu, 22 Oct 87 08:41:56 pdt
Return-Path: <kempf@hplabsz>
Received: from hplabsz by hplabsz; Thu, 22 Oct 87 09:41:28 pdt
To: "David A. Moon" <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Cc: Common-Lisp-Object-System@sail.stanford.edu
Subject: Re: indefinite extent of call-next-method
X-Mailer: mh6.5
In-Reply-To: Your message of Wed, 21 Oct 87 12:57:00 -0400.
<19871021165723.1.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Thu, 22 Oct 87 08:41:18 PDT
Message-Id: <7120.561915678@hplabsz>
From: kempf%hplabsz@hplabs.HP.COM
> I don't find Jim's argument convincing at all. To my mind,
> call-next-method is a function that is closed over the identity
> of the next method and the arguments to be passed to it, just
> as a function defined by labels with a free reference that is
> captured in an outer scope is closed over the variable in the
> free reference. In both cases it's equally true and equally
> irrelevant to the scope of the closure that the value of the
> closed-over variable is only known at run time.
The difference is that the name of the free reference in the case of a function
defined by LABELS or FLET is lexically apparent, while the identity
of the next method and arguments to be passed for CALL-NEXT-METHOD are not.
This means that a programmer trying to understand program structure for a
function defined by labels or FLET need only look at the source where the
function is passed out of scope, while, with CALL-NEXT-METHOD, the programmer
must run the code. In the case of the function, the values are dynamically
determined but the control structure is not, modulo function valued variables.
In the case of CALL-NEXT-METHOD, the control structure is dynamically
determined. Anticipating the question of "how does this differ from generic
functions or a direct call to CALL-NEXT-METHOD", in both these cases there
are lexical cues that control structure is dynamically calculated. In the
case of a generic function invocation, it is the name of the generic
function, for which the application of SYMBOL-FUNCTION will return a
generic function object. In the case of CALL-NEXT-METHOD, it is the lexical
context of a method definition. An executable entity enclosing a
CALL-NEXT-METHOD passed out of scope could be any one of a number of
things, some of which will give no clue that they enclose a CALL-NEXT-METHOD.
I understand your and Pavel's concern, however, I have a couple of problems
with this. I think it is important that the implications of making
CALL-NEXT-METHOD indefinite in extent be outlined up front, rather than
having implementors duplicate the discussion we've been going through.
This has been the case for other new concepts we've introduced, such as
generic functions. The other problem is one of design philosophy, which
is, of course, open to debate. I believe that it is usually a good idea
to offer people an "economy" option and a "luxury" option. Although
it's always dangerous to say what "most" people do, I think most
programmers won't be affected if CALL-NEXT-METHOD is implemented either
way. On the other hand, I can imagine certain "economy" CL implementations
in which implementing CALL-NEXT-METHOD as having indefinite extend may
be difficult, or adversely impact use of CALL-NEXT-METHOD in some manner.
Thus Dick's solution of specifying dynamic extent (as the "economy" option)
with "indefinite" as an allowable extention (as the "luxury" option)
appeals to me.
jak
∂22-Oct-87 1037 Moon@STONY-BROOK.SCRC.Symbolics.COM Rest of comments on chapter 1 of the draft document
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 22 Oct 87 10:37:42 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 260975; Thu 22-Oct-87 13:38:45 EDT
Date: Thu, 22 Oct 87 13:38 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Rest of comments on chapter 1 of the draft document
To: Common-Lisp-Object-System@sail.stanford.edu
Message-ID: <19871022173842.1.MOON@EUPHRATES.SCRC.Symbolics.COM>
Comments on the 20 Oct 1987 16:34 draft of the CLOS documentation
pages 1-33 through 1-39.
1-33 second bullet: "It is not allowed" is not defined
in the error terminology section. I think you mean "CLOS may be
extended to cover make-instance of a standard-type class or inclusion of
a standard type class as a superclass of a class."
(same issue as 1-16).
1-33 second bullet second sentence: I would delete the word "user-defined",
as on p.1-16, or change it to "defclass-defined."
1-33 second bullet last sentence: Remove this, we finished figuring out
which CL types have corresponding classes.
================
1-33 last bullet: Do generic-flet, generic-labels, generic-function, and
with-added-methods use standard-generic-function as the default class of
the generic function they define? I think they do.
================
1-33 last sentence: CLOS provides several predefined method combination
types, so I would change this sentence to refer to method combination
types in general not having their own meta-objects, rather than specifically
mentioning the standard method combination type. But see open issue below.
================
1-34 through 1-39: I had already reviewed this section before, but I
read it again carefully. It's almost all okay.
1-35 second paragraph: Maybe "both purposes" would be better than
"more than one purpose", since "more than one" made me think there were
more than the two purposes listed and maybe I had missed something.
1-37 first line: I'd say "It is not recommended that :initform forms
or default value forms have side-effects other than creating new objects."
since some people consider allocating storage to be a side-effect.
1-39 last line: "approved" might be a better word than "validated", since
we are trying to imply that check-initargs would definitely not signal
an error for the default initialization arguments and therefore does
not need to see them.
================
OPEN ISSUES:
1-33 last sentence: Just the other day I had to put a kludge into a
Flavors tool, instead of doing something elegant, due to the fact that
in Flavors there are no meta-objects for method-combination types. In
this case, I wanted to know what the qualifiers for primary methods
were. Perhaps when the meta-object protocol is a bit more clearly
defined, we can add meta-objects for method-combination types, so that a
method-combination type can specialize the behavior of more functions
than just compute-effective-method.
================
TYPOS:
1-36 fifth paragraph second line: "to a produce a"
1-38 last bullet: The section name in the cross-reference is spelled slightly
differently here than on the previous page.
∂22-Oct-87 1103 @RELAY.CS.NET:DUSSUD@jenner.csc.ti.com Re: Constructors
Received: from RELAY.CS.NET by SAIL.STANFORD.EDU with TCP; 22 Oct 87 11:03:30 PDT
Received: from relay2.cs.net by RELAY.CS.NET id ae28458; 22 Oct 87 12:32 EDT
Received: from csl.ti.com by RELAY.CS.NET id ab28599; 22 Oct 87 12:30 EDT
Received: from Jenner by tilde id AA17681; Thu, 22 Oct 87 10:11:42 CDT
Message-Id: <2770902739-3696863@Jenner>
Date: Thu, 22 Oct 87 10:12:19 CDT
From: Patrick H Dussud <DUSSUD%jenner.csc.ti.com@RELAY.CS.NET>
To: Danny Bobrow <Bobrow.pa@XEROX.COM>
Cc: kempf%hplabsz@hplabs.hp.com, common-lisp-object-system@SAIL.STANFORD.EDU
Subject: Re: Constructors
In-Reply-To: Msg of 21 Oct 87 16:39 PDT from Danny Bobrow <Bobrow.pa@xerox.com>
Date: 21 Oct 87 16:39 PDT
From: Danny Bobrow <Bobrow.pa@xerox.com>
Subject: Re: Constructors
jak: I don't think the difference between;
(make-foo :name 'bar :number-of-widgits 50)
and:
(make-instance 'foo :name 'bar :number-of-widgits 50)
is sufficiently large to constitute a useful addition in
abstraction.
pd The difference is the same as between
(send object :do-this ) and (do-this object).
I don't understand the analogy at all.
If the interface to my program is a bunch of SEND messages, I expose (to
my user)the fact that I am using object programming. Sometimes this is
fine, sometimes I want to be more abstract. Generic functions give me
this abstraction. If the consing interface of my program is a bunch of
MAKE-INSTANCE, I expose the fact that I am using object programming. In
this sense, a constructor function gives me an abstraction for consing,
like generic functions give me the abstraction for programming.
pd You do that by adding the following option in the defclass:
(:CONSTRUCTOR make-bar-foo (number-of-widgits &aux (name 'bar)))
This option is textually close to the initargs declaration,
which is another advantage over a separate constructor function.
1) How does the &aux get added to the argument list of a constructor?
How does this do what jak asked for?
I am including the relevant part from Moon's proposal:
Each parameter supplies the value of
one initarg, determined by the following rules:
- If a parameter variable name is EQ to an initarg name, the parameter
supplies the value of that initarg.
- If a parameter variable name is not EQ to any initarg name, but the symbol
in the keyword package with the same name as the parameter variable
name is EQ to an initarg name, the parameter supplies the value of that
initarg.
- If neither rule succeeds, signal an error.
The second rule exists because initarg names are often keyword symbols, which
are not valid as variable names.
-constructor-lambda-list- allows all of the standard lambda-list features that
DEFUN allows.
2) This option is not textually close to any inherited initarg
declarations. The fact that it is close to some and not all has large
confusion potential.
It is not more confusing that the :DEFAULT-INITARGS option, and
certainly less than a separate constructor definition.
On any architecture, if you implement MAKE-INSTANCE by
interpreting the various data structures (initargs list, default
initargs), it is going to be costly. You will need a mechanism to
generate some specialized code reflecting the interpretation for a
particular class.
This is clearly a good thing.
The question it is better to focus it on calls to make-instance, or is
it better to combine this optimization with an automatic function
generation facility, with other features? The former seems like the
"general mechanism" to me (pd says "I think it is better to
agree one a general mechanism.")
I see moon's proposal being a good combination of desirables features.
Patrick.
∂22-Oct-87 1054 Moon@STONY-BROOK.SCRC.Symbolics.COM Re: indefinite extent of call-next-method
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 22 Oct 87 10:54:44 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 260998; Thu 22-Oct-87 13:55:24 EDT
Date: Thu, 22 Oct 87 13:55 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: indefinite extent of call-next-method
To: kempf%hplabsz@hplabs.HP.COM
cc: Common-Lisp-Object-System@sail.stanford.edu
In-Reply-To: <7120.561915678@hplabsz>
Message-ID: <19871022175524.2.MOON@EUPHRATES.SCRC.Symbolics.COM>
I said I didn't have an opinion on this issue and I wasn't going to
say anything, but having once opened my mouth, I can't let this kind
of reasoning go by.
Date: Thu, 22 Oct 87 08:41:18 PDT
From: kempf%hplabsz@hplabs.HP.COM
> I don't find Jim's argument convincing at all. To my mind,
> call-next-method is a function that is closed over the identity
> of the next method and the arguments to be passed to it, just
> as a function defined by labels with a free reference that is
> captured in an outer scope is closed over the variable in the
> free reference. In both cases it's equally true and equally
> irrelevant to the scope of the closure that the value of the
> closed-over variable is only known at run time.
The difference is that the name of the free reference in the case of a function
defined by LABELS or FLET is lexically apparent, while the identity
of the next method and arguments to be passed for CALL-NEXT-METHOD are not.
Come on! The lexical bindings of CALL-NEXT-METHOD and NEXT-METHOD-P are
put in automatically by the DEFMETHOD macro. Suppose they looked like this:
(flet ((next-method-p ()
(not (null clos-internal:next-method-function)))
(call-next-method (&rest arguments)
(unless clos-internal:next-method-function
(error "There is no next method"))
(apply clos-internal:next-method-function
(or arguments clos-internal:next-method-arguments))))
...body of method...)
Yes, the identity of the next method and arguments are not lexically
apparent, just as the values of the freely-referenced variables in a
flet are not lexically apparent. I think you're confusing the names
with the values. The -only- way I see that call-next-method is
different from other lexically local functions is that its definition is
put in by a macro, thus is not lexically apparent in the original source
code. The reason for that of course is so we don't have to document the
names and contracts of the particular variables it looks at to decide
what to do, leaving implementations some freedom.
The only thing I can think is that you people arguing for dynamic extent
instead of indefinite extent have in the back of your minds that the
variables I have called clos-internal:next-method-function and
clos-internal:next-method-arguments in the example above should be
special variables rather than lexical variables, and they get dynamically
bound by generic function dispatch. But we already determined
long ago that that can't work; I don't want to spend the time to dredge
up the mail reference, but consider this contrived example:
(defmethod gf1 ((x class-1) f)
(funcall f))
(defmethod gf2 ((x class-2))
(gf1 (slot-value x 'foo) #'call-next-method))
The point here is that even with dynamic extent, call-next-method
can be called inside a generic-function call that is different from
the one whose next method it refers to. We want the next method for
gf2, not the next method for gf1. This next example is even better
since only one generic function is involved:
(defmethod gf3 ((x t) n f)
n)
(defmethod gf3 ((x class-1) n f)
(if (zerop n)
(funcall f)
(gf3 x (1- n) #'(lambda ()
(* (funcall f)
(call-next-method))))))
(gf3 (make-instance 'class-1) 6 #'(lambda () 1))
should return 720, but would return 0 if special variables
were used to control call-next-method.
This means that a programmer trying to understand program structure for a
function defined by labels or FLET need only look at the source where the
function is passed out of scope, while, with CALL-NEXT-METHOD, the programmer
must run the code.
It's true that to know which particular method CALL-NEXT-METHOD is going
to call, one has to know what the applicable methods are, which can vary
at run time. Isn't that more or less the whole point of the existence
of CALL-NEXT-METHOD? To me, this doesn't seem to have any bearing on
what the extent of CALL-NEXT-METHOD should be. I guess you see it
differently.
In the case of the function, the values are dynamically
determined but the control structure is not, modulo function valued variables.
In the case of CALL-NEXT-METHOD, the control structure is dynamically
determined.
I can't reconcile these two sentences. Is the control structure in
CALL-NEXT-METHOD anything other than function valued variables?
Anticipating the question of "how does this differ from generic
functions or a direct call to CALL-NEXT-METHOD", in both these cases there
are lexical cues that control structure is dynamically calculated. In the
case of a generic function invocation, it is the name of the generic
function, for which the application of SYMBOL-FUNCTION will return a
generic function object. In the case of CALL-NEXT-METHOD, it is the lexical
context of a method definition. An executable entity enclosing a
CALL-NEXT-METHOD passed out of scope could be any one of a number of
things, some of which will give no clue that they enclose a CALL-NEXT-METHOD.
I don't disagree with that, but can't see how it's relevant.
I understand your and Pavel's concern, however, I have a couple of problems
with this. I think it is important that the implications of making
CALL-NEXT-METHOD indefinite in extent be outlined up front, rather than
having implementors duplicate the discussion we've been going through.
This has been the case for other new concepts we've introduced, such as
generic functions. The other problem is one of design philosophy, which
is, of course, open to debate. I believe that it is usually a good idea
to offer people an "economy" option and a "luxury" option. Although
it's always dangerous to say what "most" people do, I think most
programmers won't be affected if CALL-NEXT-METHOD is implemented either
way.
I agree that passing a closure of CALL-NEXT-METHOD upward will be quite rare.
This is why I don't care much about this issue. I see it as only an academic
issue of language cleanliness, rather than something that will make a big
difference to users; the latter issues are the ones I care more about. Of
course I'd rather see a simpler and cleaner language too, if we can agree.
On the other hand, I can imagine certain "economy" CL implementations
in which implementing CALL-NEXT-METHOD as having indefinite extend may
be difficult, or adversely impact use of CALL-NEXT-METHOD in some manner.
Thus Dick's solution of specifying dynamic extent (as the "economy" option)
with "indefinite" as an allowable extention (as the "luxury" option)
appeals to me.
I still can't see how the issues for CALL-NEXT-METHOD are different from
the issues for any lexically local function, yet CLtL does not offer
implementations the choice of only implementing "downward" funargs.
∂22-Oct-87 1108 Moon@STONY-BROOK.SCRC.Symbolics.COM Keene comments on Chapter 1
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 22 Oct 87 11:08:22 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 261017; Thu 22-Oct-87 14:09:25 EDT
Date: Thu, 22 Oct 87 14:09 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Keene comments on Chapter 1
To: Sonya E. Keene <skeene@STONY-BROOK.SCRC.Symbolics.COM>
cc: common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: <19871022153612.9.SKEENE@JUNCO.SCRC.Symbolics.COM>
Message-ID: <19871022180926.3.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Thu, 22 Oct 87 11:36 EDT
From: Sonya E. Keene <skeene@STONY-BROOK.SCRC.Symbolics.COM>
In general, the spec seems to be coming together nicely. I think it
reads better than it used to, and the tone is quite consistent
throughout.
I agree with this, but forgot to say so in my earlier comments. I may
be "madly" reviewing the document, but so far I haven't found anything
to make me mad. Chapter 1 seems to be in excellent shape and there
should be no problems finishing it. I'm about to start reading Chapter 2.
1-30, Standard Method Combination
I think the standard method combination should have a name, such as
"standard-method-combination". That name should be able to be given
to the :method-combination option to defgeneric, etc. It should be
noted as one of the Built-in Method Combination types. Just because it
is the default doesn't mean that it shouldn't have a name.
I strongly agree. The name should be just "standard" I think, rather
than the longer name, since the other m-c types have short names.
Method combination types aren't in the same namespace as anything else,
so they don't need to tack "-method-combination" onto the end of their
name to distinguish them.
1-31
We don't say here what happens if a generic function is called and
there is no applicable method at all. Presumably an error is signaled.
Should say that it calls no-applicable-method, and maybe mention that
the default method for that signals an error.
∂22-Oct-87 1129 Masinter.pa@Xerox.COM Re: indefinite extent of call-next-method
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 22 Oct 87 11:29:17 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 22 OCT 87 11:24:58 PDT
Date: 22 Oct 87 11:23 PDT
From: Masinter.pa@Xerox.COM
Subject: Re: indefinite extent of call-next-method
To: Common-Lisp-Object-System@sail.stanford.edu
Message-ID: <871022-112458-5149@Xerox>
For what its worth (which I hope isn't much), I've found the arguments
for indefinite convincing enough that I'm happy to change my vote from
"dynamic" to "indefinite".
My concern was that dynamic extent might not be implementable in some
situations, and I think I've seen how it is.
Part of my motivation for changing my vote is that I believe
categorically that "optional extensions" should be strongly discouraged
whenever possible, and, when present out of necessity, detectable by
well-known *features*, and their use lexically determinable.
∂22-Oct-87 1227 RPG Extent
To: common-lisp-object-system@SAIL.Stanford.EDU
Implementability is not the same as semantics. Methods are not functions.
(Methods include functions as parts. In fact, they can have generic
functions as parts.)
This debate is or ought to be about what methods are and what generic
functions are. Virtually all arguments I have seen that argue that
indefinite is correct also apply to TAGBODY's and GO's. If a method is
not a function, what is the etymology of ``CALL-NEXT-METHOD.''
Imagine a generic function with many methods - broken down into roughly
equal numbers of :around methods, :before methods, primary methods, and
:after methods. Suppose the generic function is invoked and after a couple
of primary methods are executed, a closure is thrown out that captures
CALL-NEXT-METHOD. Two years later someone stumbles across this closure and
FUNCALL's it. We're all happy to see the primary methods complete, and the
intended :after and :around methods ignored? (Of course, they didn't
complete the first time either, though the :before methods were executed.)
To me the execution of a generic function is a black box, just as TAGBODY
is. Because it is a black box, my understanding of the semantics of it
naturally includes the fact that CALL-NEXT-METHOD has ``hidden state.''
That is, to me an activation of a generic function includes imposing a
control structure on the methods and causing the functional objects
associated with methods to be invoked according to that control structure.
CALL-NEXT-METHOD is part of the control structure but not all of it. This
can be seen because the ``capturing of hidden state'' in my example does
not capture enough of the state to cause the generic function to complete.
If the method combination type were a linear CALL-NEXT-METHOD chain, the
effect would be the completion of the second part of the generic function.
Therefore, interrupting it strikes me as undesirable. Secondly, behavior
such as shown in my example strikes me as undesirable.
It is important for you to understand that my arguments about hidden state
follow from a decision about a principle - the black-box nature of the
execution of generic functions. They do not follow from imagining an
implementation and then reasoning about it. If you do not believe in the
black-box nature of the execution of generic functions, you will construct
arguments, semantics, and implementations that eliminate the hidden state.
If I were to accept the clear-box nature of generic function execution, I
would also explain the semantics with a nest of closures.
-rpg-
∂22-Oct-87 1303 Moon@STONY-BROOK.SCRC.Symbolics.COM Comments on chapter 2, through defgeneric
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 22 Oct 87 13:03:20 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 261181; Thu 22-Oct-87 16:04:12 EDT
Date: Thu, 22 Oct 87 16:04 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Comments on chapter 2, through defgeneric
To: Common-Lisp-Object-System@sail.stanford.edu
Message-ID: <19871022200408.9.MOON@EUPHRATES.SCRC.Symbolics.COM>
2-6: This hasn't changed from 87-002, but I find the way the value of
add-method is described confusing. It isn't made perfectly clear
that the value is always eq to the first argument, rather than being
a copy of it with modifications. I'd prefer to write
"Values: {\it generic-function} is returned."
Compare the way it's done for change-class on 2-10, which is unambiguous,
but a little verbose.
================
2-7: The text that was in the previous version saying that the name
CALL-NEXT-METHOD only has a function definition within the lexical
scope of a method body got lost. We have to say something about this.
I think the most reasonable thing might be that outside the lexical
scope of a method body, CALL-NEXT-METHOD designates a function that
signals an error if called. We also have to say whether the lexical
scope of CALL-NEXT-METHOD includes forms in a method's lambda-list.
I prefer "yes", because in Flavors it used to be "no", and several
users complained so we had to change it. The implementation is
slightly more difficult, but only very slightly.
================
2-7 second Arguments paragraph: In one place this says an error is
signalled, in another it says the results are undefined, when bad
arguments are passed to call-next-method. Which is right? I don't
remember for sure but my notes from the the most recent meeting
indicate "signals an error." Also, the last sentence on this page
belongs in this paragraph, not in the paragraph that it is in.
================
2-11 last paragraph: This never says what the problem being compounded
is. It's that after changing the class of an argument, the methods
now executing or about to be executed might no longer be applicable.
================
2-20: the description of the slot options is a bit inconsistent about
whether it calls them "options" or "slot options". The introductory
phase for all but :initarg says just "option". I think I'd prefer
saying "slot option" everywhere when discussion slot options, although
that can get a bit verbose. In any case the style should be made consistent.
================
2-20 first bullet: "the setf generic function named generic-function-name"
should be "the generic function named (setf generic-function-name)".
================
2-20 last hyphenated bullet, last sentence: What it says here is slightly
oversimplified. If a class C1 defines a shared slot named S, a subclass
C2 can avoid sharing S without itself containing a slot specifier for S
in its defclass form, if C3 is a superclass of C2, C3 contains a slot
specifier for S, and C3 precedes C1 in the CPL of C2. There is probably
a clearer way to say what I just said.
================
2-21 second bullet: "The expression (typep value value-specifier) will
be true for the value stored in the slot" doesn't conform to the error
terminology introduced in chapter 1. I think we mean something like "If
the expression (typep value value-specifier) is not true for the value
stored in the slot, the results are undefined" but maybe this needs to
be phrased differently to clarify that what is undefined is for a program
to perform an action that would cause that expression to become untrue.
Also clarify that the type check does not apply to an uninitialized slot,
since such a slot does not have a value at all.
================
2-21: Just a reminder to everyone that the constructor writeup here is
not what anyone is proposing. It is neither exactly my proposal, nor
of course is it the null proposal. I presume we're letting it be until
we agree on what to do.
================
2-22 last bullet: remove this, with-slots no longer depends on the
class definition.
================
2-22 2/3 down the page: Change "No class options are inherited" to
"No class options except :default-initargs are inherited".
================
2-22 third paragraph from the bottom: "the initial value of the slot
is unspecified": this is incorrect. Change the phrase to "the slot
is uninitialized".
================
2-22 second paragraph from the bottom: :initarg can also appear more
than once in a slot description.
================
2-22 last paragraph: :default-initargs can also appear more than once in
a defclass.
================
2-24 fourth paragraph: The calls to fboundp and symbol-function are
missing quote marks. In the second sentence, new-value should be in
italics, not bold. Can this be rephrased to avoid introducing the term
"setf generic function"? Perhaps this paragraph could be merged into
the second paragraph, simply saying that -name- can be a symbol or
a setf-list. Then the fboundp/symbol-function rules wouldn't have to
be stated twice.
2-24 I'm not sure I understood the double square bracket notation used
in this chapter, but it appears to be saying that defgeneric is only
allowed one option. Maybe this is just a typo of a missing asterisk?
But maybe the syntax could be simplified by making -method-description-
a subcase of -option-. I'm not sure that -method-specifier- needs to
be a separate syntatic nonterminal symbol; why not merge this into
-method-description-?
2-24 I'd prefer not to have separate syntax for lambda-list and setf-lambda-list,
since this requires the reader to study them to figure out what is different.
It would be better to use one syntax and say in text that the new-value is
the first required argument (and therefore there must be at least one required
parameter). Affects 2-26 fifth paragraph, 2-28 fourth paragraph too.
2-24 I'm not sure we want to allow the (var) form for an optional parameter
specifier in defgeneric. The 87-002 document was ambiguous here, but I had
read it as allowing only a symbol as an optional parameter specifier, so I
was surprised to see that the other form was being allowed now too. Similarly
for keyword parameter specifiers, I would allow var and ((keyword var)), but
would forbid (var). The (var) forms seem to me likely to mislead someone
into thinking that default value forms are permitted here. I admit this is
a matter of taste.
2-25 last line: (eql -object-) should be (eql -form-) since -form- is
a form that gets evaluated at the time the defgeneric is evaluated, and
the value of -form- is the object that an argument has to be eql to to
satisfy the parameter specializer. Appears again on 2-27 fifth bullet.
2-26 discussion of optimize declaration: change "defmethod form" to
"defmethod form or method-description".
2-27 "specialized-setf-lambda-list" is mentioned here, but is not in the syntax.
It can be removed.
================
TYPOS:
2-20 last bullet: ":initform argument" should be ":initform slot option",
in two places.
2-22 first Remarks paragraph: remove the reference to change-class.
2-28 second Remarks paragraph: "a anonymous"
∂22-Oct-87 1306 @Score.Stanford.EDU:kempf%hplabsz@hplabs.HP.COM Re: indefinite extent of call-next-method
Received: from SCORE.STANFORD.EDU by SAIL.STANFORD.EDU with TCP; 22 Oct 87 13:06:22 PDT
Received: from hplabs.HP.COM (hplabs.hpl.hp.com.#Internet) by SCORE.STANFORD.EDU with TCP; Thu 22 Oct 87 13:05:19-PDT
Received: from hplms2 by hplabs.HP.COM with SMTP ; Thu, 22 Oct 87 13:06:31 PDT
Received: from hplabsz.hpl.hp.com by hplms2; Thu, 22 Oct 87 13:06:13 pdt
Return-Path: <kempf@hplabsz>
Received: from hplabsz by hplabsz; Thu, 22 Oct 87 14:05:46 pdt
To: "David A. Moon" <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Cc: common-lisp-object-system@SAIL.Stanford.EDU
Subject: Re: indefinite extent of call-next-method
X-Mailer: mh6.5
In-Reply-To: Your message of 22 Oct 87 12:27:00 -0700.
Date: Thu, 22 Oct 87 13:05:39 PDT
Message-Id: <10603.561931539@hplabsz>
From: kempf%hplabsz@hplabs.HP.COM
> It is important for you to understand that my arguments about hidden state
> follow from a decision about a principle - the black-box nature of the
> execution of generic functions. They do not follow from imagining an
> implementation and then reasoning about it. If you do not believe in the
> black-box nature of the execution of generic functions, you will construct
> arguments, semantics, and implementations that eliminate the hidden state.
> If I were to accept the clear-box nature of generic function execution, I
> would also explain the semantics with a nest of closures.
This also explains what I was trying to get at, but Dick seems to have
expressed it more clearly. We seem to have a disagreement as to the fundamental
semantics. I'm willing to say "Tio" if you feel strongly about it, and
considering Masinter's comment about discouraging optional extensions, go
with indefinite.
jak
∂22-Oct-87 1318 Bobrow.pa@Xerox.COM Re: Extent
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 22 Oct 87 13:18:08 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 22 OCT 87 13:17:27 PDT
Date: 22 Oct 87 13:17 PDT
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Re: Extent
In-reply-to: Dick Gabriel <RPG@SAIL.Stanford.EDU>'s message of 22 Oct 87
12:27 PDT
To: RPG@SAIL.Stanford.EDU
cc: common-lisp-object-system@SAIL.Stanford.EDU
Message-ID: <871022-131727-5334@Xerox>
To me the execution of a generic function is a black box, just
as TAGBODY is. Because it is a black box, my understanding of the
semantics of it naturally includes the fact that CALL-NEXT-METHOD
has ``hidden state.'' That is, to me an activation of a generic
function includes imposing a control structure on the methods and
causing the functional objects associated with methods to be
invoked according to that control structure. CALL-NEXT-METHOD is
part of the control structure but not all of it. This can be seen
because the ``capturing of hidden state'' in my example does not
capture enough of the state to cause the generic function to
complete. If the method combination type were a linear
CALL-NEXT-METHOD chain, the effect would be the completion of the
second part of the generic function.
To me the execution of a generic function is a clear box. Because the
user, through compute-effective-method, and its user interace
define-method-combination, is constructing the effective method from a
set of functions the he/she explicitly handles, the operation of this
clear box is well defined. I agree with Moon that the only reason not
to publicize the name is to allow implementtion freedom So this argues
for indefinite extent.
danny
∂22-Oct-87 1338 RPG Clear Versus Black Box
To: common-lisp-object-system@SAIL.Stanford.EDU
To the author of the generic function, the box is clear - but only during
that authorship. To the user it is black during execution. Therefore any
construct that opens a window into it is forbidden.
The actions of any FORTRAN program are well-defined. I believe we all
agree that FORTRAN was not well defined.
``I agree with Moon that the only reason not to publicize the name is to
allow implementtion freedom.''
If this would be the only reason, then the clarity of the box is
irrelevant.
-rpg-
∂22-Oct-87 1424 Pavel.pa@Xerox.COM Comments on comments on Chapter 1
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 22 Oct 87 14:23:53 PDT
Received: from Semillon.ms by ArpaGateway.ms ; 22 OCT 87 14:15:27 PDT
Date: Thu, 22 Oct 87 14:15:21 PDT
From: Pavel.pa@Xerox.COM
Subject: Comments on comments on Chapter 1
In-reply-to: <19871022033419.0.MOON@EUPHRATES.SCRC.Symbolics.COM>
To: Common-Lisp-Object-System@sail.stanford.edu
Message-ID: <871022-141527-5413@Xerox>
I agree strongly with Moon that the concept of "setf generic function"
is now essentially bankrupt and that we shouldn't give it any real
emphasis in the proposal.
Moon says:
1-3 sixth paragraph: "ordered set" should be "list" in two places,
to avoid implying that duplicates are eliminated from the "set" of
parameter specializers or the "set" of qualifiers.
1-23 first paragraph under Introduction to Methods: same comment.
I would rather that the word used here was "sequence" instead of "list",
just because "sequence" is a bit less evocative of a particular Lisp
data structure.
Moon says:
1-11 last sentence: needs to be updated with a correction I sent
earlier,
because :default-initargs can appear more than once in a defclass.
Perhaps I'm just missing something, but what's the use of multiple
:default-initargs options?
Moon says:
1-16 fourth paragraph last sentence: "It is not allowed" is not defined
in the error terminology section. I think you mean "CLOS may be
extended to cover make-instance of a standard-type class or inclusion
of
a standard type class as a superclass of a class."
I like this wording much better. The other wording, aside from being
undefined, implied to me that such extensions were not acceptable.
Simon says (oops, I mean Moon says):
1-23 last bullet: "(EQL -object-)" should be "(EQL -form-)", because
in a parameter specializer name, we have a form that is to be evaluated
to produce the object that appears in the parameter specializer. The
paragraph immediately following is wrong where it says "otherwise N
equals P" for this reason. We changed this when we changed QUOTE to
EQL.
So, to test my understanding, "(EQL -form-)" is a parameter specializer
name and "(EQL -object-)" is the resulting parameter specializer, where
-object- is the result of evaluating -form-. Is this right?
Moon says:
1-17 I still think it's wrong for list to be more specific than symbol
in the CPL of null. Consider the print-object methods. Also consider
the introjection of symbol between list and sequence, a surprising CPL.
I agree with this. I was surprised when I saw that LIST was more
specific than SYMBOL.
Sonya says:
1-17, Figure 1-1
The column header "Superclasses" doesn't make it clear that the order
of
these classes is from most to least specific. In my draft of this
the
column header was "Class Precedence List", which did make this clear.
I would also prefer "Class Precedence List" to "Superclasses" here.
Sonya says:
1-21, 3rd paragraph
"Ordinary functions and generic functions are called with identical
syntax." I can't remember for sure, but I believe we decided that
generic functions must have at least one required argument. If so,
this is one (minor) syntactic difference between ordinary and generic
functions.
If this has, indeed, been decided, the document should say so somewhere.
Does it? I could imagine uses for generic functions without arguments.
For example, the only distinction could be in the qualifiers, which
could, perhaps, be integers implementing some sort of method priority
scheme. Was there a real reason for this decision, if indeed it has
been made?
Sonya and Moon say:
1-30, Standard Method Combination
I think the standard method combination should have a name, such as
"standard-method-combination". That name should be able to be given
to the :method-combination option to defgeneric, etc. It should be
noted as one of the Built-in Method Combination types. Just because
it
is the default doesn't mean that it shouldn't have a name.
I strongly agree. The name should be just "standard" I think, rather
than the longer name, since the other m-c types have short names.
Method combination types aren't in the same namespace as anything
else,
so they don't need to tack "-method-combination" onto the end of
their
name to distinguish them.
Rather than add one more symbol in the LISP package that has no
intrinsic meaning (e.g., no value), I would like to see this named
:STANDARD. The only reason the various other built-in m-c types aren't
named with keywords is to make their association with the Lisp operators
clear.
Pavel
∂22-Oct-87 1446 Moon@STONY-BROOK.SCRC.Symbolics.COM Comments on comments on Chapter 1
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 22 Oct 87 14:46:45 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 261315; Thu 22-Oct-87 17:47:10 EDT
Date: Thu, 22 Oct 87 17:47 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Comments on comments on Chapter 1
To: Pavel.pa@Xerox.COM
cc: Common-Lisp-Object-System@SAIL.STANFORD.EDU
In-Reply-To: <871022-141527-5413@Xerox>
Message-ID: <19871022214711.7.MOON@EUPHRATES.SCRC.Symbolics.COM>
Line-fold: No
Date: Thu, 22 Oct 87 14:15:21 PDT
From: Pavel.pa@Xerox.COM
1-3 sixth paragraph: "ordered set" should be "list" in two places,
to avoid implying that duplicates are eliminated from the "set" of
parameter specializers or the "set" of qualifiers.
1-23 first paragraph under Introduction to Methods: same comment.
I would rather that the word used here was "sequence" instead of "list",
just because "sequence" is a bit less evocative of a particular Lisp
data structure.
Good idea. I like "ordered sequence" here.
Perhaps I'm just missing something, but what's the use of multiple
:default-initargs options?
defclass' philosophy appears to be to allow all options and slot options
to appear multiple times unless repetition has to be forbidden because
it would be meaningless. I think multiple :default-initargs options
just act like they were concatenated.
So, to test my understanding, "(EQL -form-)" is a parameter specializer
name and "(EQL -object-)" is the resulting parameter specializer, where
-object- is the result of evaluating -form-. Is this right?
Right. At Dick's request I mailed him a rewrite of this portion of this
section that I think should clarify everything better than my comment.
Moon says: ....
I agree with this. I was surprised when I saw that LIST was more
specific than SYMBOL.
Thank you.
[name of] Standard Method Combination
Rather than add one more symbol in the LISP package that has no
intrinsic meaning (e.g., no value), I would like to see this named
:STANDARD. The only reason the various other built-in m-c types aren't
named with keywords is to make their association with the Lisp operators
clear.
I don't understand what you mean by "intrinsic meaning". Binding to
a method-combination type is as intrinsic as binding to a value in my book.
However, I have no objection to using a keyword as the name, other than
that we'll have to change the second sentence under Arguments on page 2-29
slightly.
∂22-Oct-87 1458 Pavel.pa@Xerox.COM Re: Comments on comments on Chapter 1
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 22 Oct 87 14:58:38 PDT
Received: from Semillon.ms by ArpaGateway.ms ; 22 OCT 87 14:56:09 PDT
Date: Thu, 22 Oct 87 14:56:04 PDT
From: Pavel.pa@Xerox.COM
Subject: Re: Comments on comments on Chapter 1
In-reply-to: <19871022214711.7.MOON@EUPHRATES.SCRC.Symbolics.COM>
To: Common-Lisp-Object-System@SAIL.STANFORD.EDU
Message-ID: <871022-145609-5495@Xerox>
I said, in reference to the name for standard method combination:
Rather than add one more symbol in the LISP package that has no
intrinsic meaning (e.g., no value), I would like to see this named
:STANDARD. The only reason the various other built-in m-c types
aren't
named with keywords is to make their association with the Lisp
operators
clear.
Moon replied:
I don't understand what you mean by "intrinsic meaning". Binding to
a method-combination type is as intrinsic as binding to a value in my
book.
However, I have no objection to using a keyword as the name, other
than
that we'll have to change the second sentence under Arguments on page
2-29
slightly.
I think that there's no qualitative difference between the argument
:OVERWRITE to the :IF-EXISTS parameter of OPEN and the argument VARIABLE
to the second parameter of DOCUMENTATION. Yet, in Common Lisp, one of
these is required to be a keyword and the other is required to be in the
LISP package. I think that there are a lot of these kinds of symbols
that should all have been keywords.
Pavel
∂22-Oct-87 1521 Bobrow.pa@Xerox.COM Re: Clear Versus Black Box
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 22 Oct 87 15:21:47 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 22 OCT 87 15:17:19 PDT
Date: 22 Oct 87 15:17 PDT
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Re: Clear Versus Black Box
In-reply-to: Dick Gabriel <RPG@SAIL.Stanford.EDU>'s message of 22 Oct 87
13:38 PDT
To: RPG@SAIL.Stanford.EDU
cc: common-lisp-object-system@SAIL.Stanford.EDU
Message-ID: <871022-151719-5532@Xerox>
To the author of the generic function, the box is clear - but
only during that authorship. To the user it is black during
execution. Therefore any construct that opens a window into it is
forbidden.
To the author of any function, its actions are clear. To the user using
it, it is opaque. I see no difference between the opacity of using a
closure over an flet function, and one using call-next-method. Both
insides are apparent to the function writer; both are opaque to the
closure user. It is how the program writer views a method that I am
concerned with. It is that person who is exporting something that has
indefinite extent.
danny
∂22-Oct-87 1536 Bobrow.pa@Xerox.COM Re: Clear Versus Black Box
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 22 Oct 87 15:21:47 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 22 OCT 87 15:17:19 PDT
Date: 22 Oct 87 15:17 PDT
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Re: Clear Versus Black Box
In-reply-to: Dick Gabriel <RPG@SAIL.Stanford.EDU>'s message of 22 Oct 87
13:38 PDT
To: RPG@SAIL.Stanford.EDU
cc: common-lisp-object-system@SAIL.Stanford.EDU
Message-ID: <871022-151719-5532@Xerox>
To the author of the generic function, the box is clear - but
only during that authorship. To the user it is black during
execution. Therefore any construct that opens a window into it is
forbidden.
To the author of any function, its actions are clear. To the user using
it, it is opaque. I see no difference between the opacity of using a
closure over an flet function, and one using call-next-method. Both
insides are apparent to the function writer; both are opaque to the
closure user. It is how the program writer views a method that I am
concerned with. It is that person who is exporting something that has
indefinite extent.
danny
∂22-Oct-87 1544 Moon@STONY-BROOK.SCRC.Symbolics.COM Second set of comments on chapter 2
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 22 Oct 87 15:44:06 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 261398; Thu 22-Oct-87 18:38:03 EDT
Date: Thu, 22 Oct 87 18:38 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Second set of comments on chapter 2
To: Common-Lisp-Object-System@SAIL.STANFORD.EDU
Message-ID: <19871022223800.9.MOON@EUPHRATES.SCRC.Symbolics.COM>
These comments cover defgeneric (slightly revised from what I mailed
out earlier) through remove-method.
2-24 fourth paragraph: The calls to fboundp and symbol-function are
missing quote marks. In the second sentence, new-value should be in
italics, not bold. Can this be rephrased to avoid introducing the term
"setf generic function"? Perhaps this paragraph could be merged into
the second paragraph, simply saying that -name- can be a symbol or
a setf-list. Then the fboundp/symbol-function rules wouldn't have to
be stated twice.
2-24 I'm not sure I understood the double square bracket notation used
in this chapter, but it appears to be saying that defgeneric is only
allowed one option. Maybe this is just a typo of a missing asterisk?
But maybe the syntax could be simplified by making -method-description-
a subcase of -option-. I'm not sure that -method-specifier- needs to
be a separate syntatic nonterminal symbol; why not merge this into
-method-description-?
2-44, 2-46, 2-48, 2-77: ditto
2-24 I'd prefer not to have separate syntax for lambda-list and setf-lambda-list,
since this requires the reader to study them to figure out what is different.
It would be better to use one syntax and say in text that the new-value is
the first required argument (and therefore there must be at least one required
parameter). Affects 2-26 fifth paragraph, 2-28 fourth paragraph too.
2-44, 2-48, 2-77: ditto
2-24 I'm not sure we want to allow the (var) form for an optional parameter
specifier in defgeneric. The 87-002 document was ambiguous here, but I had
read it as allowing only a symbol as an optional parameter specifier, so I
was surprised to see that the other form was being allowed now too. Similarly
for keyword parameter specifiers, I would allow var and ((keyword var)), but
would forbid (var). The (var) forms seem to me likely to mislead someone
into thinking that default value forms are permitted here. I admit this is
a matter of taste.
2-44, 2-48, 2-77: ditto
2-25 last line: (eql -object-) should be (eql -form-) since -form- is
a form that gets evaluated at the time the defgeneric is evaluated, and
the value of -form- is the object that an argument has to be eql to to
satisfy the parameter specializer. Appears again on 2-27 fifth bullet.
2-26 discussion of optimize declaration: change "defmethod form" to
"defmethod form or method-description".
2-27 "specialized-setf-lambda-list" is mentioned here, but is not in the syntax.
It can be removed.
================
2-30 end of third bullet: "but this is not required" should perhaps be
"this is the default, but is not required", since -operator- defaults to -name-.
2-30 third paragraph from bottom of page last sentence: "define by the
define-method-combination macro", insert "the short form of".
================
2-36 last Purpose paragraph: I don't think we need the concept of "setf
generic function", so I'd like to see this paragraph go away.
2-37 second paragraph: ditto.
2-36 last line: (eql -object-) should be (eql -form-). Also maybe
-symbol- should be -class-name- for increased clarity.
2-37 fourth paragraph: ditto. Here we need to explain about -object-
being the value of -form-, as on 1-23.
================
2-40 Add missing bullets: "The form (documentation -symbol- 'variable)
returns the documentation string of the special variable or constant
named by the symbol. The form (documentation -symbol- 'structure)
returns the documentation string of the {\bf defstruct} structure named
by the symbol."
================
2-42 second Purpose paragraph: This is wrong, isn't it? Shouldn't it
say the same thing as defgeneric says, namely if (fboundp -name-) is
nil, a new generic function is created and stored there, otherwise
if (symbol-function -name-) is not a generic function, signal an error.
================
2-42 first Arguments paragraph second sentence: I think we can delete
this sentence, the concept of setf generic functions isn't useful.
================
2-54 syntax: delete the italicized word "initargs". The make-instance
generic function doesn't have any keyword parameters of its own. In
the second arguments paragraph, change "The -initargs- argument is" to
"The remaining arguments are".
================
2-54 first remarks paragraph: I think this is misleading. Instantiating
a standard type class has to be "may be extended" rather than "signals
an error", since in a given implementation a standard type class can
be implemented as a standard class. The paragraph as written is not
actually wrong, because it carefully refers to what the metaclass actually
is rather than whether the class is documented as a standard type class.
However, I think there is plenty of scope for confusion here and the
wording should be clarified somehow.
================
2-56: I don't like the use of -old-class- as the name of the argument to
make-instances-obsolete. There isn't anything old about the class object,
it remains in effect. I'd rather it was just named -class-.
================
2-57 add to Arguments section: If -method-list- is nil and :operator is
:call-next-method, the result is nil.
2-57 last paragraph: Delete.
================
2-60: I think method-qualifiers belongs in chapter 3. I know it's
referenced on page 2-32, I still think it belongs in chapter 3.
================
OPEN ISSUES:
2-37 second Remarks paragraph: We need to decide whether defmethod
creates a new method object or modifies the existing one, and say
explicitly which it is. I prefer modifying the existing one, and
the way add-method is described suggests to me that this is what is
intended, but I think Gregor disagrees.
2-55: I suspect more initargs are needed when creating an instance
of standard-method. Certainly something has to be done to make the
method's keyword parameter keyword names available, because of the
way keyword arguments to generic functions now work. Do the metafolks
have a suggestion here?
================
TYPOS:
2-28 second Remarks paragraph: "a anonymous"
2-34 line 6: "(progn" should be indented. The two make-method-call
forms that are inside the progn should be indented another space or
two to make the nesting structure more obvious.
2-23 In the first "define-method-combination and", delete "()" from
the methods clause, so unqualified methods will not be accepted.
2-42 third Purpose paragraph: "that has different value", add "a".
2-42 fourth Purpose paragraph: "and there are no methods" should
be "or there are no methods".
2-61 purpose: "next-method-s" should be "next-method-p".
================
∂22-Oct-87 1554 RPG 0-ary generic functions
To: common-lisp-object-system@SAIL.Stanford.EDU
I believe this idea tickled us when we were discussing delegation
in Palo Alto. The idea was to have every generic function have at least
one required parameter so that no-applicable-method would have something
to discriminate on. After I heard this the next thing I remembered was a
guy in a green coat waving a small bottle of ammonia under my nose.
I think we flushed this requirement. Anyone else remember it?
-rpg-
∂22-Oct-87 1606 @STONY-BROOK.SCRC.Symbolics.COM,@EUPHRATES.SCRC.Symbolics.COM:Moon@STONY-BROOK.SCRC.Symbolics.COM 0-ary generic functions
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 22 Oct 87 16:06:30 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via INTERNET with SMTP id 261452; 22 Oct 87 19:07:31 EDT
Date: Thu, 22 Oct 87 19:07 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: 0-ary generic functions
To: common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: The message of 22 Oct 87 18:54 EDT from Dick Gabriel <RPG@SAIL.Stanford.EDU>
Message-ID: <19871022230724.4.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: 22 Oct 87 1554 PDT
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>
I believe this idea tickled us when we were discussing delegation
in Palo Alto. The idea was to have every generic function have at least
one required parameter so that no-applicable-method would have something
to discriminate on. After I heard this the next thing I remembered was a
guy in a green coat waving a small bottle of ammonia under my nose.
I think we flushed this requirement. Anyone else remember it?
I think Dick is right: We flirted with, but in the end did not adopt,
a restriction that a generic function must have at least one required
parameter.
∂22-Oct-87 1622 Bobrow.pa@Xerox.COM Re: Comments on comments on Chapter 1
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 22 Oct 87 16:22:21 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 22 OCT 87 15:32:24 PDT
Date: 22 Oct 87 15:32 PDT
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Re: Comments on comments on Chapter 1
In-reply-to: Pavel.pa's message of Thu, 22 Oct 87 14:15:21 PDT
To: Pavel.pa@Xerox.COM
cc: Common-Lisp-Object-System@sail.stanford.edu
Message-ID: <871022-153224-5558@Xerox>
Moon says:
1-17 I still think it's wrong for list to be more specific than symbol
in the CPL of null. Consider the print-object methods. Also consider
the introjection of symbol between list and sequence, a surprising CPL.
Pavel says
I agree with this. I was surprised when I saw that LIST was
more specific than SYMBOL.
The motivating example for this was something like:
(defmethod some-mapper ((x listp) fn)
(when x (funcall fn (car x)) (some-mapper (cdr x) fn))
(defmethod some-mapper ((x symbolp) fn)
(some-mapper (look-up-in-table x *table*) fn)
Here one wants the recursion to NIL to be handled in the listp case
without having to think about the method on symbolp. What is an example
in which one would want this another way. I think we should in this
case be driven by some examples, since this pun in Lisp is
atheoretic.(NIL is the same as empty list)
∂22-Oct-87 1622 Bobrow.pa@Xerox.COM Re: Comments on comments on Chapter 1
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 22 Oct 87 16:22:40 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 22 OCT 87 16:21:14 PDT
Date: 22 Oct 87 16:21 PDT
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Re: Comments on comments on Chapter 1
To: Common-Lisp-Object-System@sail.stanford.edu
Message-ID: <871022-162114-5666@Xerox>
Moon:
1-17 I still think it's wrong for list to be more specific than
symbol in the CPL of null. Consider the print-object methods.
Also consider the introjection of symbol between list and sequence,
a surprising CPL.
I understand the first point. This comes to the point of whether one
wants to print NIL
as ()
or NIL
I don't understand the second point. What do you mean by introjection
here? Show the surprise please (not that I wasn't surprised --- I just
couldn't open the box).
danny
∂22-Oct-87 1622 Bobrow.pa@Xerox.COM Re: First round of comments on the draft document
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 22 Oct 87 16:22:31 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 22 OCT 87 16:07:36 PDT
Date: 22 Oct 87 16:07 PDT
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Re: First round of comments on the draft document
To: Moon@STONY-BROOK.SCRC.Symbolics.COM
cc: Common-Lisp-Object-System@sail.stanford.edu
Message-ID: <871022-160736-5631@Xerox>
================
1-16 fourth paragraph last sentence: "It is not allowed" is not
defined in the error terminology section. I think you mean "CLOS
may be extended to cover make-instance of a standard-type class or
inclusion of a standard type class as a superclass of a class."
I think the concept of standard-type-class was one we had eliminated. I
think a potentially better way to describe these this mapping is:
"The classes corresponding to predefined Common Lisp data types can be
one of two types. There are those that are implemented specially in the
implementation, and these have metaclass built-in-class. For these
built-in classes, an error is signalled if a user tries to create an
instance of such a class using make-instance. An example of such a
class is integer. Some classes corresponding to predefined Common Lisp
data types may be implemented as instances of the standard metaclass.
For example, ratio or rational might be such classes (or stream if that
gets included). For these, instances can be made using make-instance.
It is implementation dependent which of the Common Lisp data type
classes are implemented in each way."
I suggest that where ever the expression "standard type class" is now
used, we use either built-in-class if we are referring to implementation
issues, and "Common Lisp data type classes" when we are referring to the
mapping.
Question: Will we allow specialization of built-in-classes. An example
of the use of this is having a general Newton-Rafson iteration method on
number, and allowing a new specialization of number that could inherit
such a method.
∂22-Oct-87 1631 Bobrow.pa@Xerox.COM Re: 0-ary generic functions
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 22 Oct 87 16:31:40 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 22 OCT 87 16:29:22 PDT
Date: 22 Oct 87 16:29 PDT
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Re: 0-ary generic functions
In-reply-to: Dick Gabriel <RPG@SAIL.Stanford.EDU>'s message of 22 Oct 87
15:54 PDT
To: RPG@SAIL.Stanford.EDU
cc: common-lisp-object-system@SAIL.Stanford.EDU
Message-ID: <871022-162922-5707@Xerox>
I believe this idea tickled us when we were discussing
delegation in Palo Alto. The idea was to have every generic
function have at least one required parameter so that
no-applicable-method would have something to discriminate on. After
I heard this the next thing I remembered was a guy in a green coat
waving a small bottle of ammonia under my nose.
I think we flushed this requirement. Anyone else remember it?
As the guy in the green coat, I remember flushing it. It went the way
of making the second arg to no-applicable-method be the first arg of the
original call to the generic function. So to keep Dick awake becasue he
and Linda are doing such a marvelous editing job, consider this glitch
as flushed.
danny
∂22-Oct-87 1840 Moon@YUKON.SCRC.Symbolics.COM comments on some standard type classes
Received: from SCRC-YUKON.ARPA by SAIL.STANFORD.EDU with TCP; 22 Oct 87 18:40:21 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by YUKON.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 281061; Thu 22-Oct-87 21:37:18 EDT
Date: Thu, 22 Oct 87 21:37 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: comments on some standard type classes
To: Common-Lisp-Object-System@SAIL.STANFORD.EDU
In-Reply-To: <871022-162114-5666@Xerox>,
<871022-153224-5558@Xerox>
Message-ID: <19871023013700.6.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: 22 Oct 87 16:21 PDT
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Moon:
1-17 I still think it's wrong for list to be more specific than
symbol in the CPL of null. Consider the print-object methods.
Also consider the introjection of symbol between list and sequence,
a surprising CPL.
I understand the first point. This comes to the point of whether one
wants to print NIL
as ()
or NIL
I don't understand the second point. What do you mean by introjection
here? Show the surprise please (not that I wasn't surprised --- I just
couldn't open the box).
The natural direct superclasses of null are list and symbol, in some
order. The CPL of list is (list sequence t), of symbol is (symbol t).
What surprised me was to see the CPL of null be (null list symbol
sequence t), which has symbol inserted in the middle of list's CPL.
Usually one expects to see non-intersecting superclass trees kept
disjoint in the CPL, thus I would have expected to see (null symbol list
sequence t) or at worst (null list sequence symbol t). The only way to
get (null list symbol sequence t) from the standard CPL algorithm is if
sequence is a direct superclass of null.
Date: 22 Oct 87 15:32 PDT
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
The motivating example for this was something like:
(defmethod some-mapper ((x listp) fn)
(when x (funcall fn (car x)) (some-mapper (cdr x) fn))
(defmethod some-mapper ((x symbolp) fn)
(some-mapper (look-up-in-table x *table*) fn)
Here one wants the recursion to NIL to be handled in the listp case
without having to think about the method on symbolp.
I guess. It's actually a bit strange that the list method thinks it's
really important to be called for both empty and non-empty lists, but
the first thing it does is to split into two disjoint code sequences,
one for empty lists and the other for non-empty lists. It makes me
wonder why you didn't write
(defmethod some-mapper ((x list) fn)
(funcall fn (car x))
(some-mapper (cdr x) fn))
(defmethod some-mapper ((x null) fn)
(declare (ignore fn))
nil)
I think what you are really objecting to is that there is no class name
for the subclass of SYMBOL that includes all symbols other than NIL.
The Common Lisp type system doesn't need a name for that, because you
can say (and symbol (not null)), but CLOS doesn't allow that as a
parameter specializer name.
Of course if your first method had been
(defmethod some-mapper ((x sequence) fn)
(map nil fn x))
it would not have worked, with the CPL as currently in the document.
That's another way of making my "introjection" point.
What is an example in which one would want this another way.
Well, there's the one I already mentioned:
;; Simplified to ignore *print-escape*, *print-case*
(defmethod print-object ((x symbol) stream)
(maybe-print-package-prefix x stream)
(write-string (symbol-name symbol) stream))
;; Simplified to ignore *print-length*, *print-pretty*
(defmethod print-object ((x list) stream)
(do ((c #\( #\space))
((atom x))
(write-char c stream)
(print-object (pop x) stream))
(when x
(write-string " . " stream)
(print-object x stream))
(write-char #\) stream))
Here we want the symbol method when x is NIL.
Now of course you're going to tell me that CLOS does have a class name
for the subclass of LIST that includes all lists other than (), and
therefore it's easier to fix my example to conform to your CPL than it
is to fix your example to conform to my CPL. While that's true, it
seems like backwards reasoning somehow.
I guess I can accept (null list sequence symbol t) as the CPL, although
I still think (null symbol list sequence t) fits the rest of the language
a little better. Maybe that's because all the built-in symbol functions
work for nil, but only some of the built-in list functions work for nil.
Maybe I'm just confused in thinking that rplaca is a list function rather
than a cons function. Or, in other words, you should almost never put
a method on LIST, because that class is too general; put it on CONS instead.
I think we should in this
case be driven by some examples, since this pun in Lisp is
atheoretic.(NIL is the same as empty list)
Agreed, in Common Lisp NIL is always a headache one way or another.
I'm sure we can find any number of examples in support of each of the
possible CPLs, so examples may not help much to reach a decision.
Oh by the way, while I have your attention, what about the other potential
standard-type classes: function, hash-table, package, pathname,
random-state, readtable, and stream. I think these are awaiting
cleanup action to straighten out the subtype and disjointness relations
of these in the CL type system before CLOS adopts them; should these
names be listed in our document? The CL-Cleanup issue FUNCTION-TYPE
should take care of the first of these; the rest depend on
PATHNAME-HASH-TABLE-TYPE-DISTINCT, which seems to have dropped through
the cracks, unless that's just the extreme imperfection of my personal
records.
From June 10:
4. ISSUE: PATHNAME-HASH-TABLE-TYPE-DISTINCT
Mandating a bunch of types (I don't have the complete list right now)
to be disjoint from a bunch of other types (again I don't have a
complete list right now) so that they can all be made into classes
without establishing any implementation-dependent subclass relationships.
[the types STREAM, PACKAGE, PATHNAME, READTABLE and RANDOM-STATE can be
required to be disjoint from other types (e.g., as if they had been created
with DEFSTRUCT.)
I don't think we currently require structures to be a disjoint
type from vectors, etc., though this has been talked about. So that
should be part of any proposal. --Fahlman ]
∂22-Oct-87 1907 Moon@YUKON.SCRC.Symbolics.COM standard-type-class or built-in-class
Received: from SCRC-YUKON.ARPA by SAIL.STANFORD.EDU with TCP; 22 Oct 87 19:07:10 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by YUKON.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 281063; Thu 22-Oct-87 22:08:25 EDT
Date: Thu, 22 Oct 87 22:08 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: standard-type-class or built-in-class
To: Common-Lisp-Object-System@SAIL.STANFORD.EDU
In-Reply-To: <871022-160736-5631@Xerox>
Message-ID: <19871023020806.9.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: 22 Oct 87 16:07 PDT
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
I think the concept of standard-type-class was one we had eliminated. I
think a potentially better way to describe these this mapping is:
"The classes corresponding to predefined Common Lisp data types can be
one of two types. There are those that are implemented specially in the
implementation, and these have metaclass built-in-class. For these
built-in classes, an error is signalled if a user tries to create an
instance of such a class using make-instance. An example of such a
class is integer.
Add "in almost all implementations"; we can never guarantee that any class
is built-in in all implementations.
Some classes corresponding to predefined Common Lisp
data types may be implemented as instances of the standard metaclass.
For example, ratio or rational might be such classes (or stream if that
gets included). For these, instances can be made using make-instance.
It is implementation dependent which of the Common Lisp data type
classes are implemented in each way."
I suggest that where ever the expression "standard type class" is now
used, we use either built-in-class if we are referring to implementation
issues, and "Common Lisp data type classes" when we are referring to the
mapping.
I remember we discussed this, but I don't have any record of a decision
having been made. I like your suggestion here and favor adopting it,
even at this late date. I think the key thing you are suggesting is that
the CLOS standard admits that the meta-class of some objects is
implementation-dependent, but having granted that, is free to be more
specific about how the meta-class controls the behavior.
We'd want to add "No portable program can depend on whether a Common Lisp
data type class is a built-in-class or a standard-class" (this phrase
is essentially lifted from the Error Terminology section).
Question: Will we allow specialization of built-in-classes. An example
of the use of this is having a general Newton-Rafson iteration method on
number, and allowing a new specialization of number that could inherit
such a method.
If a subclass of a built-in-class is a built-in-class, we cannot allow it,
since by definition only the implementor can create new built-in-classes.
Perhaps you're asking whether a standard-class can be a subclass of a
built-in-class; this is asking for trouble, because some methods on
the built-in-class are likely to depend on instances' implementation-specific
structure, and although they would be applicable to the subclass, they
would not work. I think we want to carry the current prohibition on
subclassing of standard-type-classes over to built-in-classes.
You could also be asking whether we should say that number is so general
a class that it would never be built-in to an implementation, so we will
say that number is a standard-class, even though some of its subclasses
may be built-in-classes. This bothers me too, because CLtL contains
"generic" functions such as + that are defined to work on all subtypes
of number, and if we allow adding new subtypes of number, then we have
to add a way to define methods for +, which is something that we made
an explicit non-goal back at the beginning of this effort.
∂22-Oct-87 1947 Pavel.pa@Xerox.COM My comments on Chapter 1
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 22 Oct 87 19:46:58 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 22 OCT 87 19:42:53 PDT
Date: Thu, 22 Oct 87 19:42:37 PDT
From: Pavel.pa@Xerox.COM
Subject: My comments on Chapter 1
To: Common-Lisp-Object-System@SAIL.Stanford.Edu
Message-ID: <871022-194253-5965@Xerox>
Here are those of my comments that haven't already been covered by Moon
and Sonya. Some of these are typos and some are more substantial, but I
haven't got the energy at this point to go through and separate them
out.
Pavel
Page 1-4, second paragraph, last sentence -- A typo: "the syntax of
Object System" should be "the syntax of the Object System".
Page 1-4, second set of bullets, second bullet -- Can't valid programs
rely on that error being signalled if they also specify (SAFETY 3)? I'm
generally unhappy with the phrase "at least in code compiled under one
compiler safety optimization level". I'd prefer a direct statement that
that level is 3.
Page 1-5, third bullet -- What does the clause "but they must remain
undefined" mean? Does that mean that my implementation is incorrect if
I document just which nasty bug will crop up if situation S occurs? I
can't derive any useful content from this clause.
Page 1-6, third and fourth paragraphs -- On my copy, produced by TeXing
the source with the AMFONT file in use, the not-equal symbol comes out
funny; in particular, it does not use the proper slash to cross out the
equals sign. I traced to problem to the AMFONT file. In the last six
or so lines of this, several uses of CM fonts were not changed into
their AM equivalents. Thus, our ancient Dovers used the old, OLD CM
fonts, which have a different layout of characters.
Page 1-6, eighth paragraph -- Should "class named t" be "class with the
proper name t"? I have a lot of reservations and questions about the
class-naming solution presented here, but I think I'll send them out
separately.
Page 1-7, first bullet -- Should this be "A proper name for the new
class"?
Page 1-7, sixth bullet -- I agree with Sonya (I think) that this should
say "methods for certain generic functions" rather than use the term
"appropriately named".
Page 1-8, third paragraph, first line -- "a slot which is visible"
should be "a slot that is visible"
Page 1-11, second bullet, last sentence -- "contains :type slot option"
should be "contains the :type slot option
Page 1-11, last paragraph in the section that ends here -- I found this
to be a very surprising statement until I remembered that everything
having to do with slots is defined ultimately in terms of SLOT-VALUE.
Some of my surprise could have been avoided by a mention of SLOT-VALUE
as the reason for this mildly unintuitive notion.
Page 1-13, second paragraph, fifth line -- Is there any reason this
mentions the EQ function instead of the more usual EQL function?
Page 1-13, second paragraph, last line -- a hyphen is missing in
"implementation dependent". Such a hyphen is not required except to be
consistent with other uses of "implementation-dependent", as in earlier
lines of the same paragraph.
Page 1-13, third paragraph -- Is there any way for a user to know if a
particular redefinition of a class will change "the order of slots in
storage"? I found this criterion very much out of place. Is it there
for a reason? If so, isn't it possible that there are other
implementation-dependent reasons that a class redefinition would
necessitate updating instances?
Page 1-15 -- I would like to add my voice to Moon's and Sonya's for
changing the name of this section to "Changing the Class of an
Instance".
Page 1-15, fifth paragraph -- I certainly hope that Moon is right and
that this paragraph should simply be deleted.
Page 1-16, second paragraph -- The phrase "the proper name" ignores the
possibility that, by the definition given on page 1-6, a given class can
have many proper names. Also in this paragraph, the phrase "some class
C named S" appears. I'm not sure what's meant here. Is this saying
that S = (CLASS-NAME C)? If so, it should say so more clearly. I think
that I must be missing something that supposed to have been said back on
page 1-6...
Page 1-17, table -- The contents of the table, not the headings, should
be in a fixed-pitch font.
Page 1-17, first line -- This says "Note that instances of standard
classes are type disjoint with all other types." I can't make any sense
of this.
Page 1-17 -- What is the cleanup status of the other types that we
wanted to give classes to, such as STREAM, PATHNAME, etc.?
Page 1-19, first paragraph -- The implicit "proof" here concerning the
uniqueness of a rightmost direct subclass might want ot be spelled out a
bit more. Also, in the last line, it isn't clear to me how there can be
no such candidate classes. Does someone have an example?
Page 1-19, second paragraph -- Is there a reason to use the unusual
forms "2 <= m" and "1 <= n" instead of the more common "m >= 2" and "n
>= 1"?
Page 1-19, the example -- A good example, but it would be better with
some sort of picture. Perhaps one can be pasted in or even done with
(gack!) character graphics. If the document we done in LaTeX, I'd
recommend using its "picture" environment, but it isn't...
Page 1-23, second paragraph in the new section -- In the last sentence,
the phrase "the new definition" should probably be replaced by "the
method-function object".
Page 1-23, third paragraph in the new section, second sentence -- For
clarity the word "required" should be added before the last word in the
sentence.
Page 1-23, second-to-last paragraph -- I think that the clause "if N is
a class name, then P is the class with that name" should be "if N is a
symbol and (CBOUNDP N) is true, then P is (SYMBOL-CLASS N)".
Page 1-23, last sentence -- Since GET-METHOD does not create a method,
the phrase "functional interface to method creation" should perhaps be
""functional interface to method manipulation".
Page 1-24, fourth paragraph -- I think this would be clearer written as
"This proposal specifies that all parameter specializers and parameter
specializer names are Common Lisp type specifiers."
Page 1-24, eighth paragraph -- The reason why qualifiers can't be lists
(ambiguity in the syntax of DEFMETHOD) should be mentioned. Otherwise,
this just sticks out as a weird glitch.
Page 1-25 -- I'm now confused about what the generic function's
lambda-list is used for. It appears to affect only the checking for
congruency. Is that really all it's for? If so, this seems a bit odd.
Page 1-27, third bullet -- This would be clearer, I think, as "For each
method, which other method, if any, is called when CALL-NEXT-METHOD is
invoked".
Page 1-28, fourth complete paragraph, last line -- If the method called
by invoking CALL-NEXT-METHOD is to be called the "next method" in
general, without regard to the method-combination type, then this line
should be in a different paragraph, one that doesn't so strongly tie
itself to standard method-combination.
Page 1-29, first and second bullets -- The words "primary method" at the
end of each of these should perhaps be "primary method(s)" instead,
since there can be more than one primary method.
Page 1-29, first and third ticks of the sixth bullet --
"most-specific-first" and "most-specific-last" really need the hyphens.
Page 1-29 -- I really don't like the name NEXT-METHOD-P. It sounds like
I pass it a method object and it tells me whether or not that method is
"next". Perhaps NEXT-METHOD-EXISTS-P?
Page 1-33, second bullet -- The "it is not allowed" phrase mentioned by
others pops up here as well and should be changed.
Page 1-33, third section -- The term "meta-objects" has not been defined
anywhere.
Page 1-35, third complete paragraph -- "initform" is not a word, so this
should perhaps be ":initform option".
Page 1-36, second complete paragraph -- Since an initialization argument
can be declared as valid by a method on initialize-instance, it is a bit
weird to speak of "the class that declared the initialization argument
as valid".
Page 1-38, table -- It would be nice if this were formatted as nicely as
the table on page 1-17.
Page 1-38, first sentence -- There should be a general line somewhere
stating that all generic functions defined by the proposal (unless
explicitly mentioned otherwise? Are there any exceptions?) use standard
method combination.
∂22-Oct-87 2004 @STONY-BROOK.SCRC.Symbolics.COM,@EUPHRATES.SCRC.Symbolics.COM:Moon@STONY-BROOK.SCRC.Symbolics.COM Comments on final portion of Chapter 2
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 22 Oct 87 20:04:31 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via INTERNET with SMTP id 261601; 22 Oct 87 22:42:47 EDT
Date: Thu, 22 Oct 87 22:42 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Comments on final portion of Chapter 2
To: Common-Lisp-Object-System@SAIL.STANFORD.EDU
Message-ID: <19871023024247.0.MOON@EUPHRATES.SCRC.Symbolics.COM>
These comments apply to slot-boundp through with-slots. I'll try
to comment on chapter 3 tomorrow.
2-66 first sentence: this uses the term "bound" where elsewhere in the
document we use "not uninitialized". Admittedly there is some incoherence
between the function names and the document terminology, but I think the
document should be self-consistent and specifically relate to the term
"uninitialized" here.
2-66: Add a remark that if no slot by that name exists, we do
(SLOT-MISSING (CLASS-OF instance) instance slot-name 'SLOT-BOUNDP).
2-68: ditto
2-71: ditto (cover setf case too). Also cross-reference slot-unbound.
================
2-69 slot-missing should say under Values what gets done with
the values, if you write a method that returns some instead of
signalling an error. They get returned as the values of the original
function invocation.
2-70 ditto for slot-unbound: the value is returned in place of
the slot's value.
================
2-72: symbol-class of a symbol that is not cboundp should signal
an error, not return nil.
================
2-73: Clarify how -expansion- is used. Each reference to -symbol-
as a variable, that would be in the scope of a binding of -symbol-
as a variable at the point of the SYMBOL-MACROLET, is replaced
by -expansion- (-not- the result of evaluating -expansion-).
================
2-73: symbol-macrolet is a special form rather than a macro,
if it really works the way the last Remarks paragraph says. On
the other hand, if it works by making substitutions in its body
and returning the modified body, then it's a macro. The latter
implementation is easier for implementors of course, since they
don't have to change their interpreter, compiler, and tools to
understand a new special form and new kind of macro.
================
2-74 last Purpose sentence: update-instance-structure is not called
by change-class. It's called by something that doesn't have a documented
name inside the mechanism activated by make-instances-obsolete.
================
2-74, -75: rho and theta have been interchanged in the
update-instance-structure, (setf position-x), and
(setf position-y) methods, but are correct in the position-x
and position-y methods. Theta is the one to be set to atan.
So much for the perspicuity of greek letters.
================
2-78 first sentence: "setf generic function" again.
================
2-78 second bullet: calling change-class can't be right, this creates
a new generic function, it doesn't mung an existing one.
================
2-80 first Arguments paragraph: Are we sure we want to signal an error
for with-slots of a standard-type class? Why not use the normal
slot-missing mechanism? Of course we can't actually signal an error
here, because some standard-type classes can be implemented as standard
classes. But if this was changed to speak of built-in-class, it could
signal an error, but I still think it should go through slot-missing.
2-80 third arguments paragraph: ditto.
2-80 second Arguments paragraph: delete this paragraph.
2-81 third Remarks paragraph: ditto.
================
OPEN ISSUES:
2-78: what does with-added-methods do if -name- has a function definition
already, but the function isn't generic? Does it ignore it, signal an
error, or copy it into a default method? Signalling an error seems
safest.
================
TYPOS:
2-69 first Remarks paragraph: remove two spurious right parentheses.
2-73 first Remarks paragraph: "into calls to generic function", add "s".
2-75 first bullet: "each local slot in current class definition",
add "the".
2-78 paragraph 2: that's "defgeneric", not "def-generic".
2-78 first bullet: "has different value", add "a".
2-80 last Arguments paragraph: "the use of symbol", add "a".
================
∂22-Oct-87 2252 RPG Pavel's Comments
To: common-lisp-object-system@SAIL.Stanford.EDU
``Page 1-4, second set of bullets, second bullet -- Can't valid programs
rely on that error being signalled if they also specify (SAFETY 3)? I'm
generally unhappy with the phrase "at least in code compiled under one
compiler safety optimization level". I'd prefer a direct statement that
that level is 3.''
I don't to make CLOS depend on things that might change in Common Lisp
if I don't have to. Why state ``3'' when ``at least one'' will do?
``Page 1-5, third bullet -- What does the clause "but they must remain
undefined" mean? Does that mean that my implementation is incorrect if
I document just which nasty bug will crop up if situation S occurs? I
can't derive any useful content from this clause.''
As I mentioned in my message of July 8 containing the original proposal
which was accepted, this is to prevent implementations from using
the ``is an error'' out from Common Lisp. In Common Lisp, ``it is an
error'' means that no valid Common Lisp program should cause this situation
to occur and that the results are ``completely undefined.'' Steele goes on
to say that ``some particular implementation might ... define the effects and
results for such a situation.'' Steele mentions that ``must not'' means
``is an error.''
I have heard people argue as follows:
``It is an error to adjust an array that was not created with the
:adjustable argument non-nil. Therefore the results are undefined.
Therefore an implementation can define the behavior. Therefore, it is
ok to adjust an array created with the :adjustable argument nil.''
I want to prevent this. It's ok for your implementation to document that
the results are harmless, but I would prefer that you not state what they
are.
The other comments look good and duplicate a lot of Moon's comments, virtually
all of which are being incorporated. I expect the same will be true here.
Thanks, Pavel.
-rpg-
∂23-Oct-87 0845 @Score.Stanford.EDU:kempf%hplabsz@hplabs.HP.COM Re: Constructors
Received: from SCORE.STANFORD.EDU by SAIL.STANFORD.EDU with TCP; 23 Oct 87 08:45:08 PDT
Received: from hplabs.HP.COM (hplabs.hpl.hp.com.#Internet) by SCORE.STANFORD.EDU with TCP; Fri 23 Oct 87 08:38:40-PDT
Received: from hplms2 by hplabs.HP.COM with SMTP ; Fri, 23 Oct 87 08:44:31 PDT
Received: from hplabsz.hpl.hp.com by hplms2; Fri, 23 Oct 87 08:44:09 pdt
Return-Path: <kempf@hplabsz>
Received: from hplabsz by hplabsz; Fri, 23 Oct 87 09:43:42 pdt
To: Patrick H Dussud <DUSSUD%jenner.csc.ti.com@RELAY.CS.NET>
Cc: common-lisp-object-system@SAIL.STANFORD.EDU
Subject: Re: Constructors
X-Mailer: mh6.5
In-Reply-To: Your message of Wed, 21 Oct 87 13:57:03 -0500.
<2770829823-15823760@Jenner>
Date: Fri, 23 Oct 87 08:43:39 PDT
Message-Id: <21284.562002219@hplabsz>
From: kempf%hplabsz@hplabs.HP.COM
> Most programmers will want to name their constructors in a way which
> is reflective of their function, to construct a particular class. Thus,
> if they change the class name, it would make sense to change the
> constructor name, so that the name continues to reflect the function.
> Whether they change a constructor function name or a class name in
> a MAKE-INSTANCE form makes little difference. Thus, for the price of
> yet another DEFCLASS construct, you get very little in the way of
> additional abstraction. And, as has been argued, programmers who
> want to do this will do it anyway. Most programmers are going to
> want to do things like:
>
> (defun make-bar-foo (widgits)
>
> (make-instance 'foo :name 'bar :number-of-widgits widgits))
> You do that by adding the following option in the defclass:
> (:CONSTRUCTOR make-bar-foo (number-of-widgits &aux (name 'bar)))
I guess this example sums up the problem I have with the constructors
proposal as it stands. The semantics outlined in the original basenote
seem good, I guess I just don't like the syntax.
As a further example, consider if the programmer wants both a constructor
to make an instance with WIDGITS given and one with the name. Then the
DEFCLASS form would have to contain another :CONSTRUCTOR, with another
lambda list. One of the reasons I like Lisp over other languages is
because of the syntactic simplicity. The DEFCLASS form is already
syntatically fairly complex.
> This option is textually close to the initargs declaration, which is
> another advantage over a separate constructor function.
One could make this same argument about slot names and methods, that
the method definitions should be textually close to the slot definitions.
In fact, some Smalltalk programmers have made this argument, since this
is so in Smalltalk.
What would be the problem with having a seperate form to declare
constructors (other than incompatibility with DEFSTRUCT)? This could
even give the programmer more flexibility during the debugging phase,
since a programmer could more easily trace the "interpreted" or long
form of instantiation while debugging, then add the constructor afterwards,
during optimization, without having to modify the DEFCLASS form. While
debugging, a simple function could serve as the abstract interface.
jak
∂23-Oct-87 1041 @STONY-BROOK.SCRC.Symbolics.COM,@EUPHRATES.SCRC.Symbolics.COM:Moon@STONY-BROOK.SCRC.Symbolics.COM Comments on (the skeleton of) Chapter 3
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 23 Oct 87 10:41:33 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via INTERNET with SMTP id 262020; 23 Oct 87 13:42:31 EDT
Date: Fri, 23 Oct 87 13:42 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Comments on (the skeleton of) Chapter 3
To: Common-Lisp-Object-System@SAIL.STANFORD.EDU
Message-ID: <19871023174232.7.MOON@EUPHRATES.SCRC.Symbolics.COM>
This is my final set of initial comments on this draft of the document.
Soon, probably later today, I will send out comments based on checking
the document against my list of decisions that I think we have reached.
3-5 says the value of CHECK-INITARGS is an initialization argument list,
but 1-39 says the value is ignored. I prefer 1-39.
================
3-6, 3-9 Purpose: We have a problem with class-direct-initargs for
method-implemented initargs defined by allocate-instance methods on
individuals. This is because methods on individuals don't conform to
the usual rule of thumb that the applicable methods for a class are the
union of the applicable methods for it and its superclasses.
After some thought, I think the right approach is to leave
class-direct-initargs the way it is, but change class-all-initargs not
to be defined in terms of class-direct-initargs. Instead
class-all-initargs should be defined in terms of the union of two sets:
- the result of mapping car over class-all-slot-initargs (which in
turn is defined in terms of class-direct-slot-initargs of the class
and its superclasses)
- the union of the mapping of method-keyword-names over the result of
compute-applicable-methods.
================
3-7 Purpose: I think we should say explicitly why both the function and
the form are present. The form is only there for documentation; it is not
legitimate to try to evaluate it, since you don't have the accompanying
lexical environment. The function is there to be called. I suppose it's
not really necessary to say that the function's body might not really be
the default value form, for instance the function might be a closure of
a predefined function with the default value form in its environment, in
some cases.
3-10 Purpose: ditto
================
3-12 Values: I think the same disclaimer about modifying the returned value
used by class-all-initargs and so forth should appear here. See typos
in that disclaimer noted below.
================
3-16, 3-17, 3-18: I think the same remark about why the -class- argument
is present should appear here as appears at the bottom of page 2-69.
Also we ought to say explicitly that these functions exist to be called
by the chapter 2 functions of similar names (except when they get
optimized out at compile time).
================
OPEN ISSUES:
3-14: I think Gregor wanted to do finalize-inheritance differently, so I
won't try to do a full rewrite on this now, I'll just respond to the questions
in brackets. This should make the writeup a little better, although it still
won't be up to the standard of the earlier portions of the document.
I don't know a much more precise definition of "when anything relevant changes."
I guess this gets called whenever the slots, slot descriptions, default initargs,
or direct superclasses of the class or any of its superclasses is changed,
and finalize-inheritance has already been called at least once for the class.
In addition, it gets called when a method is added, removed, or has its
keyword argument names changed. I'm not sure whether this applies to methods
for all generic functions, or just for the initialization generic functions.
Maybe that's up to each generic function to decide? Right now in Flavors,
something analogous is called whenever the class or any of its superclasses
is redefined in any way, or if an initialization method is defined, redefined,
or undefined. We don't actually bother with the optimization of trying to
detect redefinitions that don't actually change anything.
Also perhaps it wasn't clear that this function is called by the system,
not intended to be called by the user, and is intended to have methods
written by the user.
Last purpose paragraph should be: The system-supplied methods for
finalize-inheritance conspire with the system-supplied methods for
make-instance, default-initargs, check-initargs, allocate-instance, and
initialize-instance to speed up object creation by precomputing some
information and storing it in slots of the class. This optimization
is implementation-dependent, but the finalize-inheritance mechanism that
makes such optimizations possible is standardized.
The -class- argument is a class, not a class name.
The returned value is ignored.
The Remarks field seems okay as it stands. We can't be more specific about
"things" because these are determined by the user's special optimization needs,
not something we know in advance.
================
TYPOS:
3-4 Remarks: "customize the behavior allocate-instance", add "of"
3-5: ditto
3-6 Purpose: "given calss"
3-6 Arguments: "argument" should not be in italics.
3-6 Values: "including the name", add "s".
3-6 Remarks: "undefined if the values returned by this function are modified",
I think should be "undefined if the value returned by this function is modified".
Second remarks sentence ditto. Also I think the two sentences should be in a
single paragraph.
3-7, 3-8, 3-9, 3-10, 3-11 Remarks: ditto
3-8 Purpose line 3: "followed by the name of all slots", "name" -> "names"
3-11 ditto
3-9 Purpose line 4: "that defined" -> "that were defined"
3-13 Purpose line 1: ":default-initarg", add "s"
3-13 Remarks line 1: "customize the behavior default-initargs", add "of"
3-14 Arguments line 2: "whenthe"
3-15 Purpose lines 1,2: "keywords names" -> "keyword names"
3-15 Purpose line 2: "specificers"
3-15 Purpose line 3: "instand"
================
∂23-Oct-87 1055 Moon@STONY-BROOK.SCRC.Symbolics.COM Extent
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 23 Oct 87 10:55:14 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 262042; Fri 23-Oct-87 13:56:18 EDT
Date: Fri, 23 Oct 87 13:56 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Extent
To: common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: The message of 22 Oct 87 15:27 EDT from Dick Gabriel <RPG@SAIL.Stanford.EDU>
Message-ID: <19871023175612.8.MOON@EUPHRATES.SCRC.Symbolics.COM>
Dick, I hear your "black box" argument, but I don't buy it. The
code that returns a closure of CALL-NEXT-METHOD, should someone
do that, must be on the inside of the box, i.e. lexically inside
a method.
It's probably not productive to spend any more time discussing
this right now.
∂23-Oct-87 1123 Moon@STONY-BROOK.SCRC.Symbolics.COM Re: Comments on comments on Chapter 1
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 23 Oct 87 11:23:26 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 262069; Fri 23-Oct-87 14:23:51 EDT
Date: Fri, 23 Oct 87 14:23 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: Comments on comments on Chapter 1
To: Pavel.pa@Xerox.COM
cc: Common-Lisp-Object-System@SAIL.STANFORD.EDU
In-Reply-To: <871022-145609-5495@Xerox>
Message-ID: <19871023182352.1.MOON@EUPHRATES.SCRC.Symbolics.COM>
Line-fold: No
Date: Thu, 22 Oct 87 14:56:04 PDT
From: Pavel.pa@Xerox.COM
I think that there's no qualitative difference between the argument
:OVERWRITE to the :IF-EXISTS parameter of OPEN and the argument VARIABLE
to the second parameter of DOCUMENTATION.
An important difference is that the latter is extensible and the former is not.
CLtL doesn't say DOCUMENTATION is extensible, but of course that's a bug, since
application developers are just as likely as Lisp implementors to develop new
types of named things to which they would like to attach documentation. Any
time multiple people are adding names to a namespace, we'd like to use packages
to organize that namespace. (The fact that package names are a flat namespace
rather than a hierarchy is an obvious compromise, or defect, here.)
Yet, in Common Lisp, one of
these is required to be a keyword and the other is required to be in the
LISP package. I think that there are a lot of these kinds of symbols
that should all have been keywords.
There are probably some mistakes of this type in Common Lisp, but in the
case of DOCUMENTATION, I think it's right not to use keywords. However,
I think the word should have been DEFVAR (as it was in Zetalisp, from
which Common Lisp copied this feature) rather than VARIABLE, to avoid
introducing a new symbol unnecessarily.
The original subject was whether the name of the standard method
combination type should be STANDARD or :STANDARD. I think the above
discussion doesn't really reflect on this, since we aren't proposing
to make all names of method combination types be keywords, so I'd
be content with either of those names.
∂23-Oct-87 1127 Pavel.pa@Xerox.COM Class naming
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 23 Oct 87 11:27:40 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 23 OCT 87 11:23:36 PDT
Date: Fri, 23 Oct 87 11:22:58 PDT
From: Pavel.pa@Xerox.COM
Subject: Class naming
To: Common-Lisp-Object-System@SAIL.Stanford.edu
Message-ID: <871023-112337-1027@Xerox>
On page 1-6 of the draft, there is the following paragraph:
A class can have a -name-, which is a symbol. The function CLASS-NAME
takes a class object and returns its name. The name of an anonymous
class is NIL. The function SYMBOL-CLASS takes a symbol and returns the
class associated with that symbol. We say that a class C has a -proper
name- S if C = (SYMBOL-CLASS S). Notice that it is possible that C /=
(SYMBOL-CLASS (CLASS-NAME C)).
I interpret this paragraph to mean that after the following code
executes, the class C has two proper names, ONE and TWO:
(let ((c (make-instance 'standard-class ...)))
(setf (symbol-class 'one) c)
(setf (symbol-class 'two) c))
Is this really the intent of the paragraph? I would hope not; there's
nothing particularly `proper' about that arrangement. I hope that the
paragraph really means to say that S is the -proper name- of a class C
if and only if S = (CLASS-NAME C) and C = (SYMBOL-CLASS S).
If this were the operative definition, then one could indeed say, as the
draft does in several places, "the proper name of C", since there would
be at most one such name.
Is this what's really meant on page 1-6?
Pavel
∂23-Oct-87 1133 Pavel.pa@Xerox.COM Re: Pavel's Comments
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 23 Oct 87 11:33:28 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 23 OCT 87 11:34:11 PDT
Date: Fri, 23 Oct 87 11:34:04 PDT
From: Pavel.pa@Xerox.COM
Subject: Re: Pavel's Comments
In-reply-to: "RPG@SAIL.Stanford.EDU's message of 22 Oct 87 22:52 PDT"
To: common-lisp-object-system@SAIL.Stanford.EDU
Message-ID: <871023-113411-1057@Xerox>
Me: Page 1-4, second set of bullets, second bullet -- Can't valid
programs
rely on that error being signalled if they also specify (SAFETY 3)?
I'm
generally unhappy with the phrase "at least in code compiled under
one
compiler safety optimization level". I'd prefer a direct statement
that
that level is 3.
Dick: I don't to make CLOS depend on things that might change in Common
Lisp
if I don't have to. Why state ``3'' when ``at least one'' will do?
Because I want to be able to write portable code that depends upon that
error being signaled. Saying ``at least one'' allows some bozo
implementor to decide that not signalling the error is safer than
signalling it and thus a higher safety number might turn off the
signalling. If you don't like using the number 3, how about ``at least
in code compiled under the highest compiler safety optimization level''?
Dick: I have heard people argue as follows:
``It is an error to adjust an array that was not created with the
:adjustable argument non-nil. Therefore the results are undefined.
Therefore an implementation can define the behavior. Therefore, it
is
ok to adjust an array created with the :adjustable argument nil.''
I want to prevent this. It's ok for your implementation to
document that
the results are harmless, but I would prefer that you not state
what they
are.
Why do you want to prevent this? You seem to be saying that an
implementation can't choose to implement all arrays as fully general
arrays unless they arrange for adjust-array to fail in some way on
arrays that were not originally declared to be adjustable. This seems
like a gratuitous failure. We already say that ``No valid program can
cause this situation to happen'', why not leave it at that? Since the
phrase ``but they must remain undefined'' is meaningless, I don't see
what it adds to the description.
Pavel
∂23-Oct-87 1206 Moon@STONY-BROOK.SCRC.Symbolics.COM Re: Pavel's Comments
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 23 Oct 87 12:06:22 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 262146; Fri 23-Oct-87 15:07:13 EDT
Date: Fri, 23 Oct 87 15:07 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: Pavel's Comments
To: Pavel.pa@Xerox.COM
cc: common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: <871023-113411-1057@Xerox>
Message-ID: <19871023190715.7.MOON@EUPHRATES.SCRC.Symbolics.COM>
Line-fold: No
Date: Fri, 23 Oct 87 11:34:04 PDT
From: Pavel.pa@Xerox.COM
If you don't like using the number 3, how about ``at least
in code compiled under the highest compiler safety optimization level''?
This sounds right to me.
On the adjust-array example, I would certainly oppose redefining
adjust-array of an array created with :adjustable nil to be "the results
are undefined" rather than "may be extended" as it is now. However, I
think Dick is right that there may be some circumstances in which
extensions should be forbidden, and I am certain that he is right that
we should stop confounding "the results are undefined" with "may be
extended."
∂23-Oct-87 1240 RPG Pavel
To: common-lisp-object-system@SAIL.Stanford.EDU
The paragraph about proper names was miswritten. I should read
``... We say that a class C has a proper name S if
S=(class-name C) and C=(symbol-class S). Notice that it is possible
that C\neq (symbol-class (class-name C)).'''
-rpg-
∂23-Oct-87 1247 RPG Undefined Definition
To: common-lisp-object-system@SAIL.Stanford.EDU
Pavel writes:
``Why do you want to prevent this? You seem to be saying that an
implementation can't choose to implement all arrays as fully general
arrays unless they arrange for adjust-array to fail in some way on
arrays that were not originally declared to be adjustable.''
I feel like Bork; does Pavel feel like Biden? I was not arguing
about arrays, I was arguing about the reasoning process used in this
case about arrays. If a specification says that ``it is not permissible
to do something'' or that ``one must not do something,'' then I expect
that it is not proper reasoning to turn that into ``it is permissible
to do something'' or ``it's perfectly ok to do something.''
Therefore, along with the other 3 error terms - which cover the vast majority
of all cases written about in the specification - I included the plug for
this hole.
-rpg-
∂23-Oct-87 1250 RPG Adjustable Arrays and Error Terminology
To: common-lisp-object-system@SAIL.Stanford.EDU
In fact, I would state the condition for adjusting non-adjustable arrays
to be that in the case where an attempt is made to adjust an array not
created to be adjustable, the behavior is extendable, which is what
implementors have chosen to do here.
-rpg-
∂23-Oct-87 1333 Bobrow.pa@Xerox.COM Comments on Chapter 1
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 23 Oct 87 13:33:41 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 23 OCT 87 13:34:20 PDT
Date: 23 Oct 87 13:33 PDT
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Comments on Chapter 1
To: RPG@SAIL.Stanford.EDU
cc: common-lisp-object-system@SAIL.Stanford.EDU
Message-ID: <871023-133420-1308@Xerox>
As with other commenters, I am impressed with the general high level of
quality of the chapter. I have tried to leave out those comments
already made by Moon, Sonya and Pavel, and others of my comments that I
have sent out.
1-3 Para 4. The terminology of "a generic function can be specialized
by the definition of methods" may be confusing -- since it is not
necesarily the case that what is added is more special -- specialized in
the sense that classes are specialized. Methods can be completely
independent of ones added before. How about "a generic function can be
extended by the addition of methods". Also in that paragraph and below,
the terminology of "class-specific operations" ignores individuals.
Perhaps better would be "parameter-specialized operations"
p 1-6 It might mention after the third paragraph that "A class can be
given a name by using
(setf (symbol-class <symbol>) class), but that this does not guarantee
that the class-name of class is <symbol>. A class may also have more
than one name, at most one of which is its proper name.
In the paragraph about a class precedence list being consistent with its
local precedence order, it is worth making it explicit that subclasses
always precede their supers (although that is implicit in your
definition of local precedence list)
p 1-7 para 2 you say "CLOS provides a default metaclass that is
appropriate for most programs." Please add "The default metaclass is
called standard-class." so that later we can refer to it.
p 1-8 "Slots can be accessed in two ways: by use of METHODS defined by
the defclass form, added to the appropriate generic function, and by
use of the primitive function slot-value."
A sentence here about why one defines these accessors may be in order.
"These accessors provide a more abstract interface for external users of
instances of a class. It allows implementors to later change the
definition of a class, removing the slot, but providing a method that
implements the functionality formerly captured structurally."
I support the removal of the sentence with the phrase "individual slots"
p1-9 Sometimes it is convenient to access slots from within the body of
a method or function ** simply by using the name of the slots as if they
were variables. **
p1-11 :reader :accessor paragraph. To make things more explicit, add
"If a slot specifier contains a reader or accessor option, the specified
methods are created only in the class in which the slot specifier
explicitly appears."
"A consequence of the type rule ..." Add at the end "It is an error to
assign a value to a slot that does not satisfy the type constraint."
p 1-13 There is a mention of :constructor here. We agreed to postpone
decision on constructors. I would like to see all mention of
constructors disappear from this version of the spec until agreement is
reached.
Paragraph "Note that redefining ..." The last sentence would be better
as the third sentence of that paragraph.
Last paragraph should have sentence "If there is a shared slot in the
old class definition that has the same name as a local slot in the new
class definition, the local slot in every updated instance is eql to the
value that was in the shared slot.
p1-14 "The Object System guarantees that ..." references to being
defined by defclass should be replaced by being instances of
standard-class. We have talked about mechanisms that undercut this
defclass condition, so the level of indirection is better. This is a
specification, and it is the metaclass that will count for this
guarantee.
p1-15 Changing the class of an instance
"to conform to the definiton of the SPECIFIED class."
Paragraph 2 ought to be after paragraph 3, and have a sentence added,
"This initialization is done by the default method on the
generic-function class-changed.
Para 5 should be deleted. The interesting sentence that might be added
is the one I wrote above (p1-13) for shared slot to local slot updating.
p 1-16
I have sent out a comment on this, and hope we can get rid of the
standard-type-class notion in favor of "built-in-class" as a metaclass
and "Common Lisp data type class" as a descriptive term.
I think we should put in the spec something about package stream etc,
saying that we expect them to be forced to be distinct types, and
include them as Common Lisp data type classes.
p1-18
Why is (c,c) for classes in SC added to R. This means there is never a
situation in which there is no pair in the ordering that has some
specific c as its right hand element. I am missing something I am sure.
p 1-21 in with-added-methods, we had better specify here that these are
copies of methods in the lexically visible generic function, or we may
get unwanted side effects.
p1-22 para 2 It should say that an error is signalled if there a
defgeneric is evaluated, and the name is bound to a non generic
function.
"the lambda list of the generic function is CONSTRUCTED to be congruent
with the lambda-list of the new method.
p1-23 Can both (EQL form) and (EQL object) be Common Lisp type
specifiers. The first is what is the name, the second is what is
described below. On the next page it says both parameter specializers
and parameter specializer names must be CL type specifiers.
p1-25 Point 4 "in in" --> "in"
p 1-28 Mention next-method-exists-p here (I like Pavel's suggested name
change)
p 1-33 Question about standard-type-class again. We need a different
statemetn about structure-class (I could easily imagine a CL that made
it a subclass of standard-class)
p1-35 Top line. It is not true for all metaobject programming that the
arguments are classes e.g. methods on generic-fucntion and methods. So
it should be clear here that you mean metaprogramming with respect to
initialization.
p1-38 "(This is true even if a :before method ..." This should say "if
any code has stored a slot value before the default method is run. e.g
:around, more specialized primaries using call-next-method as well as
:before.
p1-39 Is unitinitialized state better than unbound. The latter agrees
with the function names.
There is the error condition missing from the make-instance symbol case
in case the symbol is not a class-name. At least a comment ought to be
made.
∂23-Oct-87 1445 Pavel.pa@Xerox.COM Re: Undefined Definition
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 23 Oct 87 14:45:25 PDT
Received: from Salvador.ms by ArpaGateway.ms ; 23 OCT 87 14:42:27 PDT
Date: Fri, 23 Oct 87 14:42:21 PDT
From: Pavel.pa@Xerox.COM
Subject: Re: Undefined Definition
In-reply-to: "RPG@SAIL.Stanford.EDU's message of 23 Oct 87 12:47 PDT"
To: common-lisp-object-system@SAIL.Stanford.EDU
Message-ID: <871023-144227-1427@Xerox>
Dick: I feel like Bork; does Pavel feel like Biden?
I think that I'm stating my opinions in my own words, so I guess I can't
feel like Biden ...
Ahem.
Dick: If a specification says that ``it is not permissible
to do something'' or that ``one must not do something,''
then I expect that it is not proper reasoning to turn that
into ``it is permissible to do something'' or
``it's perfectly ok to do something.''
I think there's a confusion here between the specification of valid
programs and the specification of valid implementations. I guess I
can't envision a case in which I actually want to forbid an
implementation to provide a useful semantics in one of these undefined
situations. I have always interpreted the "is an error" cases as
breathing space for the implementations, since they don't have to detect
the situation or signal an error, and a warning to the programmer not to
count on any particular semantics or harmlessness.
More concisely, can you give an example of a situation that you strongly
prefer to have in the undefined category rather than the "may be
extended" category?
Pavel
∂23-Oct-87 1457 Moon@STONY-BROOK.SCRC.Symbolics.COM More comments on the draft document
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 23 Oct 87 14:57:38 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 262376; Fri 23-Oct-87 17:58:39 EDT
Date: Fri, 23 Oct 87 17:58 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: More comments on the draft document
To: Common-Lisp-Object-System@sail.stanford.edu
Message-ID: <19871023215825.9.MOON@EUPHRATES.SCRC.Symbolics.COM>
Additional comments resulting from comparing the document to my
clos-decisions file and the 87-002 amendments handout:
We need to note somewhere that SYMBOL-FUNCTION, FBOUNDP, and
FMAKUNBOUND take an optional environment argument, just like
ENSURE-GENERIC-FUNCTION, SYMBOL-CLASS, CBOUNDP, and CMAKUNBOUND.
This is necessary to be able to find a generic function object,
given its name, in the compile environment. FMAKUNBOUND may
be just for consistency, but FBOUNDP and SYMBOL-FUNCTION are to
allow ENSURE-GENERIC-FUNCTION to work.
Add to Remarks fields: The body of (DEFMETHOD -name- ...) is surrounded
by an implicit block named -name-, if that is a symbol, or -name1-, if
-name- is (SETF -name1-), by analogy with DEFUN. The same applies to
methods defined by the :METHOD option to DEFGENERIC, GENERIC-FLET,
GENERIC-LABELS, and WITH-ADDED-METHODS. There is no implicit block around
the body of a method defined by the :METHOD option to GENERIC-FUNCTION.
What can be done with method objects, e.g. can one method be added
to more than one generic function?
Gregor: I believe it should signal an error to attempt to put a method on more
than one generic function. My model of this is that if you want to do
something like that, you can take one function, use it as the method function
of multiple methods, each of which would be on a different generic function.
September: Agreed.
I don't see anything about this in the document. Should the discussion under
make-instance of how to make a method require a :generic-function initarg?
Or should there be a remark under add-method saying it can signal an error
if the method is already claimed?
Which symbols defined by the standard go in what package? I think we need to
say explicitly that we have postponed a decision on this.
2-20 second paragraph: delete "from their superclasses and so on", or
else change "superclasses" to "direct superclases". As written it doesn't
make sense, since a superclass of a superclass of C is always a superclass
of C, and might encourage confusion about the difference between a superclass
and a direct superclass.
2-65 Same comment that the value is always eq to the first argument as on 2-6
and 2-10.
∂23-Oct-87 1550 Bobrow.pa@Xerox.COM More on Class names
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 23 Oct 87 15:50:39 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 23 OCT 87 15:43:03 PDT
Date: 23 Oct 87 15:42 PDT
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: More on Class names
To: Common-Lisp-Object-System@sail.stanford.edu
Message-ID: <871023-154303-1550@Xerox>
It should be stated in chapter one that a many-one association from
symbols to classes is implemented by symbol-class and (setf
symbol-class). An INDEPENDENT association from class to symbol is
maintained by class-name and (setf class-name). Neither of these setf
functions effects the other association. defclass is specified to do
both (setf symbol-class) and (setf class-name).
∂23-Oct-87 1633 Moon@STONY-BROOK.SCRC.Symbolics.COM More on Class names
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 23 Oct 87 16:33:41 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 262473; Fri 23-Oct-87 19:34:48 EDT
Date: Fri, 23 Oct 87 19:34 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: More on Class names
To: Common-Lisp-Object-System@sail.stanford.edu
In-Reply-To: <871023-154303-1550@Xerox>
Message-ID: <19871023233437.7.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: 23 Oct 87 15:42 PDT
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
It should be stated in chapter one that a many-one association from
symbols to classes is implemented by symbol-class and (setf
symbol-class). An INDEPENDENT association from class to symbol is
maintained by class-name and (setf class-name). Neither of these setf
functions effects the other association. defclass is specified to do
both (setf symbol-class) and (setf class-name).
I agree.
∂23-Oct-87 1716 Masinter.pa@Xerox.COM Environment-arguments, MACRO-FUNCTION-ENVIRONMENT
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 23 Oct 87 17:16:42 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 23 OCT 87 17:17:25 PDT
Date: 23 Oct 87 17:17 PDT
From: Masinter.pa@Xerox.COM
Subject: Environment-arguments, MACRO-FUNCTION-ENVIRONMENT
In-reply-to: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>'s
message of Fri, 23 Oct 87 17:58 EDT
To: Common-Lisp-Object-System@sail.stanford.edu
cc: CL-Cleanup@Sail.stanford.edu
Message-ID: <871023-171725-1686@Xerox>
Moon (on CLOS list):
"We need to note somewhere that SYMBOL-FUNCTION, FBOUNDP, and
FMAKUNBOUND take an optional environment argument, just like
ENSURE-GENERIC-FUNCTION, SYMBOL-CLASS, CBOUNDP, and CMAKUNBOUND.
This is necessary to be able to find a generic function object,
given its name, in the compile environment. FMAKUNBOUND may
be just for consistency, but FBOUNDP and SYMBOL-FUNCTION are to
allow ENSURE-GENERIC-FUNCTION to work."
Related issues were discussed at some length on CL-CLEANUP. If someone
wants to write this up for cleanup, I have a file of the discussion
(under GET-SETF-METHOD-ENVIRONMENT in Jan-87 and ENVIRONMENT-ARGUMENTS
in April 87).
There seems to be a number of separable issues, but separating them is
difficult. Volunteers appreciated.
∂23-Oct-87 1851 Gregor.pa@Xerox.COM status of "object" or "standard-object"
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 23 Oct 87 18:51:05 PDT
Received: from Semillon.ms by ArpaGateway.ms ; 23 OCT 87 18:46:58 PDT
Date: Fri, 23 Oct 87 18:46 PDT
From: Gregor.pa@Xerox.COM
Subject: status of "object" or "standard-object"
To: Sonya E. Keene <skeene@STONY-BROOK.SCRC.Symbolics.COM>
cc: common-lisp-object-system@sail.stanford.edu
In-Reply-To: <871014112750.2.SKEENE@JUNCO.SCRC.Symbolics.COM>
Message-ID: <871023184641.0.GREGOR@SPIFF.isl.parc.xerox.com>
Line-fold: no
Date: Wed, 14 Oct 87 11:27 EDT
From: Sonya E. Keene <skeene@STONY-BROOK.SCRC.Symbolics.COM>
Last month we discussed whether CLOS should specify the class "object"
or "standard-object", and we didn't get anywhere.
To me, this seems to be a hole in the spec that we ought to fill up in
time for the next draft. It seems like most people believe there will
be one or more of these classes, but the spec doesn't say anything at
all about them. Unless we do something, our draft will imply that
there won't be these classes, but we will still be assuming there will
be.
In fact I think this hole manifests itself in several places. Specifically,
there are several places in the spec which refer to the "default primary
method" when in fact they should be referring to the "primary method on
object (or standard object)". The examples of this I can find right now
are:
update-instance-structure (pg 1-13)
class-changed (pg 1-15)
initialize-instance (pg 1-34)
The point in these examples is that these "system supplied" methods are
actually providing default behavior for instances with metaclass
standard-class, so they should be on the class object, thats what its
there for.
Other examples of where a particular implementation might want to have a
method on OBJECT as well as one on T are:
print-object (pg 2-63)
describe (pg 2-39)
So I think we have to include this class (I don't particularly care
about the name), and fix the places I have mentioned to refer to it.
-------
∂26-Oct-87 1032 @RELAY.CS.NET:DUSSUD@jenner.csc.ti.com "Object" Class.
Received: from RELAY.CS.NET by SAIL.STANFORD.EDU with TCP; 26 Oct 87 10:32:17 PST
Received: from relay2.cs.net by RELAY.CS.NET id af11653; 26 Oct 87 9:50 EST
Received: from csl.ti.com by RELAY.CS.NET id ab07103; 26 Oct 87 9:47 EST
Received: from Jenner by tilde id AA24621; Mon, 26 Oct 87 07:44:36 CST
Message-Id: <2771243079-7629931@Jenner>
Date: Mon, 26 Oct 87 07:44:39 CST
From: Patrick H Dussud <DUSSUD%jenner.csc.ti.com@RELAY.CS.NET>
To: common-lisp-object-system@SAIL.STANFORD.EDU
Subject: "Object" Class.
In-Reply-To: Msg of Fri, 23 Oct 87 18:46 PDT from Gregor.pa@xerox.com
In fact I think this hole manifests itself in several places. Specifically,
there are several places in the spec which refer to the "default primary
method" when in fact they should be referring to the "primary method on
object (or standard object)". The examples of this I can find right now
are:
update-instance-structure (pg 1-13)
class-changed (pg 1-15)
initialize-instance (pg 1-34)
The point in these examples is that these "system supplied" methods are
actually providing default behavior for instances with metaclass
standard-class, so they should be on the class object, thats what its
there for.
Other examples of where a particular implementation might want to have a
method on OBJECT as well as one on T are:
print-object (pg 2-63)
describe (pg 2-39)
So I think we have to include this class (I don't particularly care
about the name), and fix the places I have mentioned to refer to it.
I agree.
Patrick.
∂26-Oct-87 2146 COMMON-LISP-OBJECT-SYSTEM-mailer Some open issues
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 26 Oct 87 21:45:59 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 264295; Tue 27-Oct-87 00:04:48 EST
Date: Tue, 27 Oct 87 00:04 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Some open issues
To: Common-Lisp-Object-System@SAIL.STANFORD.EDU
Message-ID: <19871027050430.3.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: 26 Oct 87 1130 PST
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>
Note: I haven't looked at today's draft yet. But here are some comments
on open issues, some of them based on talking with Danny Bobrow and some
of them based on questions from Dick Gabriel.
1. What is the story on the idea of built-in?
The key point here is that CLOS does not specify exactly which types are
built-in. We split "standard type class" into two things: the types
that are defined in Steele's book, which are candidates for being
built-in, and the built-in-class metaclass, which defines the ones that
actually are built-in in a given implementation. So we're allowing any
Common Lisp data type to be either built-in or a standard-class in a
particular implementation, but you can check the metaclass to see if it
is built-in. Also we're allowing implementations to make new
implementation-dependent built-in types, so the only thing that's
guaranteed -not- to be built-in are the standard classes you define
yourself. Also the structure classes I guess.
Danny points out that in the future we might want to make an incompatible
change to Common Lisp to require some particular type that is already in
Steele's book to be a standard-class rather than a built-in-class, whereas
in the initial version of CLOS this will be at the implementation's option.
For instance, one might want to do this to streams. Moon speaking again:
I don't see any CLtL types that are indubitably candidates for this, so
I think we can put off that issue.
It's implied by a paragraph on p.1-17, but it could be made clearer
in the commentary on Figure 1-1 that there can be additional,
implementation-dependent elements in the class precedence lists
of these types. CLOS only requires that the elements listed by
present and be in the order specified.
I'll try to send out in a separate message a cleanup of the built-in-class
message that Danny and Gregor sent, to be more appropriate to go into the
document. It's late, I guess that message won't go out until Tuesday.
2. UPDATE-INSTANCE-STRUCTURE and CLASS-CHANGED needed to be parallel
in how and who does initialization. Danny proposes that default primary methods
handle it in both cases. My view is that unless there is some meta-object
way to eliminate the initialization step, the only way is by putting
them into a primary method that can be shadowed or eliminated.
In talking to Danny last night, I came to believe that he thinks there
would be no meta-object way to get at the initialization in this step.
Actually, all of UPDATE-INSTANCE-STRUCTURE, CLASS-CHANGED, and
INITIALIZE-INSTANCE can usefully be consistent. This means that
for all three of these the default primary method is in charge of
initializing newly added slots that are not already initialized,
by evaluating the :initform and storing the result into the slot.
For UPDATE-INSTANCE-STRUCTURE and CLASS-CHANGED, values of slots
that already existed are transported into the updated instance
by something "at the bit level", before the generic function is
called. All three of these default primary methods are permitted
to conspire with the bit level to optimize out initforms that
neither produce nor depend on side-effects, by storing them into
the slots before the generic function is called rather than in the
default primary method. This optimization is still valid, but
not useful, when the default primary method has been shadowed.
Also implementations are permitted to open-code the body of the
default primary method in a way that makes it customized to a
specific class, rather than being forced to obtain information
from the class object and interpret it. However, this does not
change the user's ability to shadow the default primary method,
thus this optimization has to be done by open-coding rather than
by automatically generating a customized method on a more specific
class than STANDARD-OBJECT (I think this is grotesque, but it's the
only way to preserve the property that apparently people find highly
desirable of being able to turn off the evaluate-the-initforms
behavior without using a :AROUND method to turn everything off).
Changes from what we have now:
INITIALIZE-INSTANCE is not changed
UPDATE-INSTANCE-STRUCTURE -- the first bullet in the Remarks goes
away. Preserving the values of old slots is done at the bit level.
CLASS-CHANGED -- responsibility for evaluating the :initforms moves
from CHANGE-CLASS to CLASS-CHANGED (in the latest version of the
document I have, chapters 1 and 2 are inconsistent about this).
Responsibility for the rest of the structural transformation
remains with CHANGE-CLASS.
I think this shows that the use of standard method combination is wrong
for all three of these, because we have to keep telling people "don't
use :before methods, you'll be surprised, and don't use primary methods
unless you really mean to shadow the primary method." However, I know
I'm not going to change any minds on that point. If I was designing
this in a vacuum, I think I would make all three of these use PROGN
:MOST-SPECIFIC-LAST method combination, and then the user would not be
able to tell, except by using :AROUND methods, whether the initforms
are done by the default primary method or by the caller, and there
would be no way to write a method that does something unexpected,
so we wouldn't have to warn people about pitfalls.
3. What's the resolution on the CPL for NULL, SYMBOL, LIST et al?
The only one that's broken is the CPL for NULL. Either (null symbol list
sequence t) or (null list sequence symbol t) would be acceptable to me
and to Danny; the real problem is the (null list symbol sequence t) that
we have now. But we could say that was just a typo. Danny said he wanted
to check with Gregor in case G. had any strong opinion. I notice the
latest draft has (null symbol list sequence t) and I'm willing to live
with that.
4. What terminology for ``default primary method'' should we use?
We should define a class named STANDARD-OBJECT (this was the best name
Danny and I came up with), which is the least specific class, except for
T, in the CPL of any instance whose meta-class is STANDARD-CLASS. The
reason for existence of STANDARD-OBJECT is to allow there to be default
methods for instances of standard classes, that don't apply to instances
of other classes (built-in, structure, what have you). I hope with some
tweaking of the English the above paragraph can go into the document.
Most of the CPL examples will need to have STANDARD-OBJECT added to them.
There are several places in the spec which refer to the "default primary
method" when in fact they should be referring to the "primary method on
standard-object". The examples of this I can find right now are:
update-instance-structure (pg 1-13)
class-changed (pg 1-15)
initialize-instance (pg 1-34)
(For class-changed, we have to say which parameter is specialized.
I think the answer is, "both").
The point in these examples is that these "system supplied" methods are
actually providing default behavior for instances with metaclass
STANDARD-CLASS, so they should be on the class STANDARD-OBJECT, that's
what it's there for.
It's also likely that an implementation would want STANDARD-OBJECT
methods for PRINT-OBJECT and DESCRIBE, in addition to the T methods.
However, for these generic functions we say only that there is always
an applicable method, we don't say how the system-supplied methods
are modularized.
(Above text was Bidenized from Gregor in part.)
5. Are methods side-effected when method functions change?
One issue is, why should methods be different from classes and generic
functions? Both defclass and defgeneric side-effect an existing object,
they don't create a new object if there already is one with the name.
Another issue seems to be what happens if an error is signalled, e.g. due
to noncongruent lambda lists? Has the existing method object already
been side-effected when that happens? In general, CLtL never says what
the state of the program is at the time an error is signalled, and would
allow an implementation to choose whether to do the error-checking first
or the side-effects first. However, we might want CLOS to be a bit
cleaner. I don't see any reason not to do the error checking before the
side-effects.
We should see if Gregor comes up with some reason at the meta-object level
why it's really important that methods be inconsistent with generic functions
and classes. But in the absence of that, I think we ought to say that
defmethod side-effects an existing method object. We haven't said what
the macro expansion of defmethod is exactly, and perhaps that's meta-object
level business, but I think it might involve a function similar to
ensure-generic-function that takes enough keyword arguments to describe
the method, and either makes a new object or updates an existing one.
6. The reason that DEFMETHOD shouldn't specialize functions like CAR defaultly
is that the compiler has already compiled a pile of stuff knowing what's up.
WITH-ADDED-METHODS created lexical environment in which the compiler can know
all about that gives. Therefore, I think that if WITH-ADDED-METHODS is asked
to extend an ordinary function, it should make that function the method
function for the default primary method.
Another point is that this effect can be simulated with GENERIC-FLET, by
writing a default method that calls the old definition of the function
name. This suggest that there can't be much harm in allowing
WITH-ADDED-METHODS to do this. My only problem in evaluating this is that
I can't figure out what WITH-ADDED-METHODS is good for in the first place.
However I agree that WITH-ADDED-METHODS should be allowed to extend an
ordinary function.
7. What about the class named OBJECT? How does it fit in?
STANDARD-OBJECT, see above.
8. If CALL-NEXT-METHOD is globally bound to a function that signals
an error, the name CALL-NEXT-METHOD has indefinite scope. Is this
what we mean to say?
Well, the name has indefinite scope, but a particular binding of the name
to a useful value (not the global one that just signals an error) only has
lexical scope. I don't know the proper way to say this, but I think it is
what we mean to say.
By your comment about CALL-NEXT-METHOD's extent including the arguments
to the method, do you mean this:
(defmethod foo ((x1 c1) ... (xn Cn)
&optional (next-fun #'(lambda () (call-next-method))))...)
I guess this is ok.
Yes, that's what I mean. I guess the precise language would be that the
scope of the binding of CALL-NEXT-METHOD to a useful function includes
forms that appear in parameter specifiers of the defmethod, of course with
the exception of forms that appear in parameter specializer names of the
defmethod, since those latter forms are evaluated at definition time, not
at generic function call time.
Implementing this is epsilonically harder than allowing call-next-method
only in the body, but it seems to be what people will expect, and I'm
sure it's not enough harder to implement for implementation difficulty
to be a consideration.
By the way, this could also be written more simply
(defmethod foo ((x1 c1) ... (xn Cn)
&optional (next-fun #'call-next-method))...)
which is why we changed call-next-method from a macro to a function.
Another open issue is that initargs you have to pass to make-instance
when making a standard-method. I think the best bet is that in addition
to the initargs already documented, you must pass :lambda-list, which
is a lambda-list from which the implementation is permitted to derive
the number of required and optional arguments, the presence of rest/key
arguments, the keyword names, for lambda-list congruence computation.
An implementation is also permitted to ignore the :lambda-list argument
and get this information from the :function argument, if in that
implementation a lambda-list can be retrieved from a function (CLtL
doesn't require that). I think the lambda-list can be anything that
meets these requirements, so it can be the specialized-lambda-list that
appears in the defmethod form, or it can be an ordinary function lambda
list, or it can be the type of stripped down lambda-list that can
be used with defgeneric. I think it's better for the derivation of
lambda-list congruence information from lambda-lists to be in the system,
rather than being reimplemented by every user, hence I suggest a lot
of freedom in what kind of lambda-list the initarg can accept. The
alternative would be to require the user to pass two numbers, a boolean,
and a list of keyword names, but I'd rather not do it that way.
∂26-Oct-87 2202 Common-Lisp-Object-System-mailer Proof of CLOS Document
Received: from SCORE.STANFORD.EDU by SAIL.STANFORD.EDU with TCP; 26 Oct 87 22:01:56 PST
Received: from hplabs.HP.COM (hplabs.hpl.hp.com.#Internet) by SCORE.STANFORD.EDU with TCP; Mon 26 Oct 87 21:58:39-PST
Received: from hplms2 by hplabs.HP.COM with SMTP ; Mon, 26 Oct 87 11:17:56 PST
Received: from hplabsz.hpl.hp.com by hplms2; Mon, 26 Oct 87 11:17:14 pst
Return-Path: <kempf@hplabsz>
Received: from hplabsz by hplabsz; Mon, 26 Oct 87 12:16:43 pst
To: lgd@sail.stanford.edu, rpg@sail.stanford.edu
Cc: common-lisp-object-system@sail.stanford.edu
Subject: Proof of CLOS Document
X-Mailer: mh6.5
Date: Mon, 26 Oct 87 11:16:40 PST
Message-Id: <1123.562274200@hplabsz>
From: kempf%hplabsz@hplabs.HP.COM
Linda & Dick:
Compliments on the fine job you've both done! I had no trouble TeXing
the document, once I found out that LaTeX didn't work and I had to
use straight TeX.
I only had an opportunity to go through the document this weekend, so
these comments may not be in time for the November meeting, but I
wanted to post them anyway. For the most part, they are simple typos
or regularization of wording. I did not have time to read the
discussion last week (sorry) so there may be some duplicates here.
CHAPTER 1:
Overall: meta-object v.s. metaobject v.s. meta-class v.s. metaclass
Might it not be a good idea to stick to one meta notation
rather than using meta-object and metaclass?
pg. 1-7: Last sentence. Shouldn't this be pharased in terms of the
error terminology?
pg. 1-9: Second last line. "The macro WITH-SLOTS invokes the function
SLOT-VALUE is to access slots."
↑↑↑↑↑
Incorrect English.
pg. 1-11: Last line. "earliest in the class precedence list" Since the
class precedence list hasn't yet been introduced, perhaps "most
specific class" would be more approprate.
pg. 1-16: 4th Paragraph, 4th line. "Each standard type class has the
class STANDARD-TYPE as a metaclass"
↑↑↑↑
Implies there may be more than one. Perhaps "as its" would be better.
pg. 1-16: 4th Paragraph. Last sentence. Again, use of the error
terminology would probably be appropriate.
pg. 1-16: 6th Paragraph. Again, this looks like a forward reference
to the CPL.
pg. 1-17: Last Paragraph. It is not clear from this what should happen
if (TYPE-OF <obj>) returns a type speciifer which is a list. Should an
error be signalled or should the CAR of the list be used? On pg. 42 of
CLtL, the description of type specifiers which are lists suggests
that the CAR should work.
pg. 1-25: List item 4. Last sentence. "in in the generic function"
typo.
CHAPTER 2:
Overall: When referring to SETF functions, the list specifying a
SETF function name is often not quoted. Example: (fboundp (setf <name>)).
If the argument had been a function symbol name, however, it would have
been quoted, since FBOUNDP is a function and therefore the arguments
are evaluated. Shouldn't this be so for SETF function names as well,
or is the assumption that (SETF <name>) is a macro which returns the
actual name of the function (e.g. expands into something like '<actual name>)?
Perhaps using the italic <setf-function-specification> would be more
appropriate.
Overall: The criterion mentioned in the first chapter for whether a
generic function is part of the metaobject protocol (at least, the
impression I obtained after reading Ch. 1) was that the generic function
operated on class objects. There are, however, several functions
in Chapter 2 which have class arguments in their interface. Leaving
aside the obvious exceptions such as CLASS-NAME which are used heavily
during interactive development, reasons for others are not so obvious.
Should either the wording in Chapter 1 be tightened up to exclude the
exceptions, or should some of the functions in Chapter 2 which discriminate
on class objects be moved to Chapter 3?
pg. 2-7: Is CALL-NEXT-METHOD a function? From the as yet incomplete
e-mail discussion, it would seem to be either a macro (if Moon's
implementation is accepted) or a special form.
pg. 2-7: 2nd Paragraph under ARGUMENTS. "the same set of applicable methods"
I think what you mean here is the effective method, since, the intent is
to avoid having to recalculate the effective method.
pg. 2-21: 2nd Paragraph. Shouldn't this be phrased in terms of the error
language?
pg. 2-26: :DECLARE description. Why prohibit INLINE and NOTINLINE? One
optimization a compiler writer might want is to have the generic function
code inserted in line. Or is the assumption that this should be controlled
in the lexical context enclosing the generic function invocation, rather
than in the definition of the generic function's interface?
pg. 2-27: Top of page. If the class name given to the :METHOD-CLASS
and :GENERIC-FUNCTION-CLASS does not specify a class whose protocol
conforms to that required for a method or a generic function, is an error
signalled? Or are these options caveat empor?
pg. 2-30: Top of page. I'm curious if the form generated is expected to
be executable. That is, if <operator> can be a keyword symbol, then the
implicit assumption is that the function cell of keywords can be
bound. I know this is possible in Symbolics CL and not in ours, also
I don't think CLtL says anything either way. Is there a Cleanup proposal
on this?
pg. 2-32: Top of page. "semantic meaning". Redundant. Should be either
"semantics" or "meaning".
pg. 2-40: 2nd bullet item, last line. Do you mean list? (SETF <name>)
is something more than a general list, I think. Perhaps function
specification?
pg. 2-57: Last line. I believe this line is out of date, because
the extension to CALL-NEXT-METHOD was adopted (i.e. allowing arguments).
pg. 2-61: VALUES. Don't you mean T or NIL? There are no true and
false types in CL.
pg. 2-61: REMARKS. Wording on the first sentence is a little rough.
"...within the method within which it is referenced." might be better
phrased as "...within the method where it is referenced."
pg. 2-73: REMARKS. Last sentence. Wording is a little rough.
"...convert variable uses into calls to generic function" might be better
phrased as "...convert variable uses into calls to generic functions".
pg. 2-74: First sentence. "The generic function UPDATE-INSTANCE-STRUCTURE
is not intended to called by..."
???
Suggest adding a "be".
CHAPTER 3
Overall: There are a couple of function descriptions with the wording:
The results are undefined if the values returned by the
function are modified.
It is permitted, but not required, for an implementation
to return values that share with internal data structures.
In the context of what the results of invoking the function being
described are, the first sentence makes no sense, because, once the
function has returned a value, further "results" are not forthcoming:
the function has completed its task. I believe what is meant here
is that the results of further operations using the Object System
may or may not be impacted by modifying returned values, depending
on whether the implementation does or does not choose to return
a shared data structure.
pg. 3-6: 2nd Paragraph. Last Sentence. "class" is misspelled as
"calss".
pg. 3-12: SYNTAX. Shouldn't the argument list be an &REST parameter,
since its size will vary depending on the number of required arguments
the generic function accepts?
pg. 3-12: I'm confused by where the effective method is calculated.
Is it this function, or is there another?
pg. 3-13: PURPOSE. The implication of the first sentence is that
<initarg list> is modified, while the last sentence specifically forbids
that. Why not simply say in the first sentence that the initialization
arguments are appended to a copy of <initarg list>?
pg. 3-14: This is pretty vague.
pg. 3-15: 1st Paragraph. "instead" misspelled as "instand".
∂27-Oct-87 0845 Common-Lisp-Object-System-mailer Proof of CLOS Document
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 27 Oct 87 08:44:52 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 264619; Tue 27-Oct-87 11:46:56 EST
Date: Tue, 27 Oct 87 11:45 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Proof of CLOS Document
To: kempf%hplabsz@hplabs.HP.COM
cc: common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: <1123.562274200@hplabsz>
Message-ID: <19871027164545.7.MOON@EUPHRATES.SCRC.Symbolics.COM>
A few comments on excerpts from your comments:
Date: Mon, 26 Oct 87 11:16:40 PST
From: kempf%hplabsz@hplabs.HP.COM
pg. 1-17: Last Paragraph. It is not clear from this what should happen
if (TYPE-OF <obj>) returns a type speciifer which is a list. Should an
error be signalled or should the CAR of the list be used? On pg. 42 of
CLtL, the description of type specifiers which are lists suggests
that the CAR should work.
Is this the page that has figure 1-1 on it? I can't find anything on that
page that looks like what you're referring to. I suspect you've uncovered
a problem here, but I can't find the problem. Note however that the
second paragraph on page 1-16, where it says (type-of I) is S if S is
the proper name of C, else C, should say that this only applies when C
is an instance of STANDARD-CLASS.
Overall: When referring to SETF functions, the list specifying a
SETF function name is often not quoted. Example: (fboundp (setf <name>)).
If the argument had been a function symbol name, however, it would have
been quoted, since FBOUNDP is a function and therefore the arguments
are evaluated. Shouldn't this be so for SETF function names as well,
or is the assumption that (SETF <name>) is a macro which returns the
actual name of the function (e.g. expands into something like '<actual name>)?
It's just missing quote marks; no hairy macro like that was intended.
Do you have page references for these typos? I think I noticed one or two,
but they're easy to overlook and you probably saw some that I missed.
Perhaps using the italic <setf-function-specification> would be more
appropriate.
That would be okay too, although offhand I think it would be better to
say '(SETF <name>) so we don't have to define one more syntactic
nonterminal symbol.
pg. 2-7: Is CALL-NEXT-METHOD a function? From the as yet incomplete
e-mail discussion, it would seem to be either a macro (if Moon's
implementation is accepted) or a special form.
CALL-NEXT-METHOD has been a function since we changed it from a macro
in late 1986 or early 1987. I'm not sure what implementation of mine
you're referring to; I don't recall proposing one this year. I proposed
one last year, which is totally out of date by now.
pg. 2-7: 2nd Paragraph under ARGUMENTS. "the same set of applicable methods"
I think what you mean here is the effective method, since, the intent is
to avoid having to recalculate the effective method.
No it really means the stronger condition that it says. Remember we spent a
long time discussing this. I don't remember all the discussion, but it may
have been that "same applicable methods" is both easier to specify precisely
and easier to compute than "same effective method".
pg. 2-26: :DECLARE description. Why prohibit INLINE and NOTINLINE? One
optimization a compiler writer might want is to have the generic function
code inserted in line. Or is the assumption that this should be controlled
in the lexical context enclosing the generic function invocation, rather
than in the definition of the generic function's interface?
Precisely. The idea is that there isn't any body in DEFGENERIC, so there
isn't any code for INLINE and NOTINLINE declarations to affect.
pg. 2-30: Top of page. I'm curious if the form generated is expected to
be executable. That is, if <operator> can be a keyword symbol, then the
implicit assumption is that the function cell of keywords can be
bound. I know this is possible in Symbolics CL and not in ours, also
I don't think CLtL says anything either way. Is there a Cleanup proposal
on this?
This moved to 2-29 in the latest draft (if things are getting shorter, that's
a good sign!). I don't see anything that implies here that an implementation
has to allow <operator> to be a keyword symbol. Certainly that was not
intended. On the other hand, I don't know of anything in CLtL that allows
implementations to forbid defining keyword symbols as functions. Anyway,
the intent here is that <operator> is the name of a function, macro, or
special form and can appear in the car of a form; precisely what objects
satisfy that criterion is defined by CL rather than CLOS.
pg. 2-40: 2nd bullet item, last line. Do you mean list? (SETF <name>)
is something more than a general list, I think. Perhaps function
specification?
(SETF <name>) is certainly a list, whatever else it is. But I note that
this is one the missing quote marks you mentioned earlier, which might
have obscured the meaning. (Page 2-39 in latest draft.)
pg. 3-12: SYNTAX. Shouldn't the argument list be an &REST parameter,
since its size will vary depending on the number of required arguments
the generic function accepts?
I don't think so, I think this argument is just a list of arguments.
pg. 3-12: I'm confused by where the effective method is calculated.
Is it this function, or is there another?
This function computes the applicable methods, not the effective method.
compute-effective-method is mentioned on 1-28, but there is no writeup
for it yet.
∂27-Oct-87 0852 Common-Lisp-Object-System-mailer status of "object" or "standard-object"
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 27 Oct 87 08:52:48 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 264645; Tue 27-Oct-87 11:54:33 EST
Date: Tue, 27 Oct 87 11:53 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: status of "object" or "standard-object"
To: Gregor.pa@Xerox.COM
cc: common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: <871023184641.0.GREGOR@SPIFF.isl.parc.xerox.com>
Message-ID: <19871027165325.8.MOON@EUPHRATES.SCRC.Symbolics.COM>
Line-fold: No
I assume there is a metaclass mechanism that allows a metaclass, such
as STANDARD-CLASS, to specify that each class that is an instance of
that metaclass or one of its submetaclasses shall contain a class,
such as STANDARD-OBJECT, as a superclass. Do we need to say anything
about that in chapter 1, or should we simply say that any standard
class has STANDARD-OBJECT and T in its CPL, without specifying how
exactly they get there?
∂27-Oct-87 1051 Common-Lisp-Object-System-mailer Some open issues
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 27 Oct 87 10:50:40 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 264818; Tue 27-Oct-87 13:52:38 EST
Date: Tue, 27 Oct 87 13:51 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Some open issues
To: Common-Lisp-Object-System@SAIL.STANFORD.EDU
In-Reply-To: <19871027050430.3.MOON@EUPHRATES.SCRC.Symbolics.COM>
Message-ID: <19871027185132.5.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Tue, 27 Oct 87 00:04 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Date: 26 Oct 87 1130 PST
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>
1. What is the story on the idea of built-in?
I'll try to send out in a separate message a cleanup of the built-in-class
message that Danny and Gregor sent, to be more appropriate to go into the
document. It's late, I guess that message won't go out until Tuesday.
This turned out to be very much more difficult than I expected. At the next
level of detail behind Danny's message of 22 October, there is a great deal
of ill-definedness and unclarity. I'll try to send something out later today,
but there is an excellent chance that it will be delayed until tomorrow.
If in the process of writing it I end up convincing myself that built-in-class
is a bad idea after all, I'll try to send something out explaining the reasoning
that got me there.
∂28-Oct-87 0856 Common-Lisp-Object-System-mailer Re: Proof of CLOS Document
Received: from SCORE.STANFORD.EDU by SAIL.STANFORD.EDU with TCP; 28 Oct 87 08:56:12 PST
Received: from hplabs.HP.COM (hplabs.hpl.hp.com.#Internet) by SCORE.STANFORD.EDU with TCP; Wed 28 Oct 87 08:52:37-PST
Received: from hplms2 by hplabs.HP.COM with SMTP ; Wed, 28 Oct 87 08:55:27 PST
Received: from hplabsz.hpl.hp.com by hplms2; Wed, 28 Oct 87 08:54:59 pst
Return-Path: <kempf@hplabsz>
Received: from hplabsz by hplabsz; Wed, 28 Oct 87 09:54:27 pst
To: "David A. Moon" <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Cc: kempf%hplabsz@hplabs.HP.COM, common-lisp-object-system@SAIL.STANFORD.EDU
Subject: Re: Proof of CLOS Document
X-Mailer: mh6.5
In-Reply-To: Your message of Tue, 27 Oct 87 11:45:00 -0500.
<19871027164545.7.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Wed, 28 Oct 87 08:54:23 PST
Message-Id: <388.562438463@hplabsz>
From: kempf%hplabsz@hplabs.HP.COM
New page numbers refer to the draft on SAIL as of Oct. 22, which
may be out of date with the current draft, since I've not had
a chance to update.
> pg. 1-17: Last Paragraph. It is not clear from this what should happen
> if (TYPE-OF <obj>) returns a type speciifer which is a list. Should an
> error be signalled or should the CAR of the list be used? On pg. 42 of
> CLtL, the description of type specifiers which are lists suggests
> that the CAR should work.
> Is this the page that has figure 1-1 on it? I can't find anything on that
> page that looks like what you're referring to. I suspect you've uncovered
> a problem here, but I can't find the problem. Note however that the
> second paragraph on page 1-16, where it says (type-of I) is S if S is
> the proper name of C, else C, should say that this only applies when C
> is an instance of STANDARD-CLASS.
Yes, this is the page with Fig. 1-1. I think what I'm trying to anticipate
is implementation problems. Re-reading the second paragraph on page 1-16,
the specification seems to be clear on this. If TYPE-OF returns a list,
then it's up to the implementation to make sure the first element is
used in SYMBOL-CLASS.
> Overall: When referring to SETF functions, the list specifying a
> SETF function name is often not quoted. Example: (fboundp (setf <name>)).
> If the argument had been a function symbol name, however, it would have
> been quoted, since FBOUNDP is a function and therefore the arguments
> are evaluated. Shouldn't this be so for SETF function names as well,
> or is the assumption that (SETF <name>) is a macro which returns the
> actual name of the function (e.g. expands into something like '<actual na
me>)?
> It's just missing quote marks; no hairy macro like that was intended.
> Do you have page references for these typos? I think I noticed one or two,
> but they're easy to overlook and you probably saw some that I missed.
I marked some of them down. Here they are:
pg. 2-24, 4th paragraph; pg. 2-36, 4th paragraph; pg. 2-40 2nd bullet item;
pg 2-42, 1st paragraph under ARGUMENTS
> pg. 2-30: Top of page. I'm curious if the form generated is expected to
> be executable. That is, if <operator> can be a keyword symbol, then the
> implicit assumption is that the function cell of keywords can be
> bound. I know this is possible in Symbolics CL and not in ours, also
> I don't think CLtL says anything either way. Is there a Cleanup proposal
> on this?
> This moved to 2-29 in the latest draft (if things are getting shorter, that's
> a good sign!). I don't see anything that implies here that an implementation
> has to allow <operator> to be a keyword symbol. Certainly that was not
> intended. On the other hand, I don't know of anything in CLtL that allows
> implementations to forbid defining keyword symbols as functions. Anyway,
> the intent here is that <operator> is the name of a function, macro, or
> special form and can appear in the car of a form; precisely what objects
> satisfy that criterion is defined by CL rather than CLOS.
As mentioned, CLtL says nothing either way about whether keyword symbols
can be defined as functions. The only reason I asked about this was because
the last sentence in that paragraph states that <operator> can be specified
by a keyword option. If there are any other implementations besides ours
which have chosen to forbid binding the function cell of a keyword symbol
to a function, this might be a problem.
∂29-Oct-87 0918 Common-Lisp-Object-System-mailer Re: Some open issues
Received: from RELAY.CS.NET by SAIL.STANFORD.EDU with TCP; 29 Oct 87 09:18:27 PST
Received: from relay2.cs.net by RELAY.CS.NET id ae24364; 29 Oct 87 10:05 EST
Received: from csl.ti.com by RELAY.CS.NET id ah27125; 29 Oct 87 10:03 EST
Received: from Jenner by tilde id AA19194; Thu, 29 Oct 87 08:43:26 CST
Message-Id: <2771505853-154858@Jenner>
Date: Thu, 29 Oct 87 08:44:13 CST
From: Patrick H Dussud <DUSSUD%jenner.csc.ti.com@RELAY.CS.NET>
To: Common-Lisp-Object-System@SAIL.STANFORD.EDU
Subject: Re: Some open issues
In-Reply-To: Msg of Tue, 27 Oct 87 00:04 EST from "David A. Moon" <Moon@scrc-stony-brook.arpa>
Another open issue is that initargs you have to pass to make-instance
when making a standard-method. I think the best bet is that in addition
to the initargs already documented, you must pass :lambda-list, which
is a lambda-list from which the implementation is permitted to derive
the number of required and optional arguments, the presence of rest/key
arguments, the keyword names, for lambda-list congruence computation.
An implementation is also permitted to ignore the :lambda-list argument
and get this information from the :function argument, if in that
implementation a lambda-list can be retrieved from a function (CLtL
doesn't require that). I think the lambda-list can be anything that
meets these requirements, so it can be the specialized-lambda-list that
appears in the defmethod form, or it can be an ordinary function lambda
list, or it can be the type of stripped down lambda-list that can
be used with defgeneric. I think it's better for the derivation of
lambda-list congruence information from lambda-lists to be in the system,
rather than being reimplemented by every user, hence I suggest a lot
of freedom in what kind of lambda-list the initarg can accept. The
alternative would be to require the user to pass two numbers, a boolean,
and a list of keyword names, but I'd rather not do it that way.
That sounds good.
I have another related question. We said at the Palo Alto meeting (If I
remember correctly) that something like
(defmethod foo ((a c1) (b c2) &key x )
...)
would result into a method which lambda list is ((a c1) (b c2) &key x)
(used for the lambda-list congruence computation),
and a function which lambda list can be (a b &key x &allow-other-keys).
It is done so because the generic function check the keywords arguments,
not the method.
If what I said is correct, the question is: When do we change/generate the
function's lambda list? Do we generate the final one during the
macroexpansion of DEFMETHOD or do we change the lambda-list during the
execution of (make-instance 'standard-method ...)?
Patrick.
∂29-Oct-87 1109 Common-Lisp-Object-System-mailer comments on revised Chapter 1
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 29 Oct 87 11:09:01 PST
Received: from JUNCO.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 267210; Thu 29-Oct-87 13:04:01 EST
Date: Thu, 29 Oct 87 13:03 EST
From: Sonya E. Keene <skeene@STONY-BROOK.SCRC.Symbolics.COM>
Subject: comments on revised Chapter 1
To: common-lisp-object-system@sail.stanford.edu
Message-ID: <19871029180349.7.SKEENE@JUNCO.SCRC.Symbolics.COM>
page 1-14, 4th paragraph:
The sentence "Implementations may choose to invoke
update-instance-structure under other circumstances as well" isn't
really true. If the implementation decides to go through this process,
it always does both steps of the process, and it never just invokes
update-instance structure.
The other problem with that sentence is that it is buried in the middle
of the description of the two-step process itself.
The paragraph should begin by making it clear that we guarantee this
two-step process happens in one circumstance (set of local slots in an
instance changes), and it might happen in other circumstances, but we
aren't listing here all the times when an implementation would decide
to do this.
Here is a suggested rewriting of the beginning of the paragraph:
"If a class is redefined in such a way that the set of local slots
accessible in an instance of the class is changed, a two-step process of
updating the instance takes place. This two-step process can happen
in other circumstances, if the implementation finds it necessary. For
example, some implementations might need to trigger this two-step
process if the order of slots in storage is changed."
page 1-15: 3rd paragraph
Delete the sentence "Implementations may choose to invoke class-changed
under other circumstances as well." This isn't true for class-changed.
The first sentence states that the two-step process only happens under
certain circumstances. This isn't right. Perhaps the first step of
the process is only triggered under certain circumstances, but the
second step (calling class-changed) happens every time change-class is
called.
page 1-15:
We should state that changing the class of an instance never affects
shared slots.
page 1-17: Figure 1-1
The column entries under "Class precedence list" aren't right; they
exclude the class itself from its own precedence list. For example,
the CPL of array is (array t), not just (t). I also think the CPLs
here should be lists (with parentheses), to be consistent with the way
CPLs are presented in "Determining the Class Precedence List".
page 1-31:
Still don't have the standard method combination listed under built-in
method combination types.
page 1-41: third paragraph
There seem to be some spurious tildes (~) appearing in two of the forms.
∂29-Oct-87 1259 Common-Lisp-Object-System-mailer Re: Some open issues
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 29 Oct 87 12:59:08 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 267493; Thu 29-Oct-87 15:59:51 EST
Date: Thu, 29 Oct 87 15:59 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: Some open issues
To: Common-Lisp-Object-System@SAIL.STANFORD.EDU
In-Reply-To: <2771505853-154858@Jenner>
Message-ID: <19871029205951.5.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Thu, 29 Oct 87 08:44:13 CST
From: Patrick H Dussud <DUSSUD%jenner.csc.ti.com@RELAY.CS.NET>
We said at the Palo Alto meeting (If I remember correctly) that something like
(defmethod foo ((a c1) (b c2) &key x )
...)
would result into a method which lambda list is ((a c1) (b c2) &key x)
(used for the lambda-list congruence computation),
and a function which lambda list can be (a b &key x &allow-other-keys).
It is done so because the generic function check the keywords arguments,
not the method.
If what I said is correct,
It is.
the question is: When do we change/generate the
function's lambda list? Do we generate the final one during the
macroexpansion of DEFMETHOD or do we change the lambda-list during the
execution of (make-instance 'standard-method ...)?
It has to be during the macro expansion of defmethod, since the :function
initarg to standard-method (although I don't have any documentation that
says this explicitly) can be a function that has already been compiled
and can't have its lambda-list mucked with.
The documentation on 2-53, 2-54 of how to create generic functions and
methods of your own is pretty unsatisfactory. It seems like a bit too
much detail to be covering under make-instance, yet it's not really
enough detail to cover all of the issues, like what does the lambda-list
of the :function have to look like? And what about making ones own
classes? I think this stuff may have to move into chapter 3 and become
documentation sections of their own for classes standard-method,
standard-class, and standard-generic-function, rather than being
tucked inside make-instance.
∂29-Oct-87 2147 Common-Lisp-Object-System-mailer standard type class
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 29 Oct 87 21:47:32 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 267958; Fri 30-Oct-87 00:48:26 EST
Date: Fri, 30 Oct 87 00:48 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: standard type class
To: Common-Lisp-Object-System@SAIL.STANFORD.EDU
Message-ID: <19871030054823.6.MOON@EUPHRATES.SCRC.Symbolics.COM>
This is a first draft.
The problems with the term "standard type class" are:
- the name is too close to "standard class" so it's easy to get confused.
- the semantics are too ill-defined. When we say "could be extended"
to allow subclassing and make-instance, this sounds like it refers to
standard type classes in general, but what it actually means is that
an individual class documented as a standard type class could be
implemented as a standard class.
- we haven't made clear enough that an object has standard-type-class
as -a- metaclass, but -the- metaclass is implementation-dependent
Suggestion:
- eliminate the term "standard type class"
- when we mean "a class that corresponds to a predefined Common
Lisp type" we should say exactly that, no need to abbreviate.
- rename the standard-type-class metaclass to built-in-class,
and clarify that it is implementation-dependent whether any
potentially built-in class is in fact built-in and has this
metaclass.
- clarify the requirements on portable programs
These are all the uses of the phrase "standard type class" (with or
without hyphens) that appear in the documentation as of a couple
days ago:
1-16 -- see rewrite below
1-34 -- see rewrite below
2-11 2nd remarks para -- delete the second sentence. We don't need
a "for example" and don't need to say anything more than that change-class
is only guaranteed to work for standard classes.
2-22 1st remarks para -- delete the third sentence. The section
"Redefining Classes" already covered the rules here.
2-54 last remarks para -- delete, this has already been covered and
doesn't need to be repeated.
2-79 1st args para last sentence -- this doesn't belong here, delete it.
Perhaps slot-value should say that it signals an error if given an
instance of a built-in class (I don't think it calls slot-missing
in that case.)
On page 1-16, the rest of the section after the first three paragraphs
is replaced by the following (edited from the TEX source on SAIL):
Many but not all of the predefined Common Lisp type specifiers have a
corresponding class with the same proper name as the type. For example,
the type {\bf array} has a corresponding class named {\bf array}. No
type specifier that is a list, such as {\tt (vector double-float 100)},
has a corresponding class. No type defined by {\bf deftype} has a
corresponding class.
Each class that corresponds to a predefined Common Lisp type specifier
can be implemented in one of three ways, at the discretion of each
implementation. It can be a {\bit standard class\/}, of the kind
defined by {\bf defclass}, a {\bit structure class\/}, defined
by {\bf defstruct}, or a {\bit built-in class\/}, implemented in
a special, non-extensible way. For example, most Common Lisp
implementations reserve a particular bit pattern for representing
conses. In such an implementation, {\bf cons} is a built-in class.
Built-in classes have restricted capabilities, because of their special
representation. Attempting to use {\bf defclass} to add new subclasses
to a built-in class signals an error. Calling {\bf make-instance} to
create an instance of a built-in class signals an error. Many built-in
classes do not have slots and calling {\bf slot-value} signals an error.
Redefining a built-in class or using {\bf change-class} to change the
class of an instance to or from a built-in class signals an error.
However, built-in classes {\it can\/} be used as parameter specializers
in methods.
A portable program must assume that all classes that correspond to
predefined Common Lisp type specifiers are built-in classes. In a
particular implementation one of these classes might be a standard
class, but in other implementations it could be a built-in class.
Thus a portable program may not define a subclass, make an instance,
reference a slot, redefine, or change-class a potentially built-in class.
It is possible to distinguish standard from built-in classes by checking
the metaclass. A standard class is an instance of {\bf standard-class}
or of a subclass of it. A built-in class is an instance of
{\bf built-in-class} or of a subclass of it. Note that the metaclass
of a class that corresponds to a predefined Common Lisp type specifier
is implementation-dependent.
Each structure type created by {\bf defstruct} without using the
{\bf :type} option has a corresponding class. This class is an
instance of {\bf structure-class}. A portable program must assume
that {\bf structure-class} is a subclass of {\bf built-in-class}
and suffers the same restrictions. Whether {\bf structure-class}
in fact is a subclass of {\bf built-in-class} is implementation-dependent.
The {\bf :include} option of {\bf defstruct} creates a direct subclass
of the class that corresponds to the included structure.
The purpose of specifying that many of the standard Common Lisp types
have a corresponding class is to allow users to write methods that
discriminate on these types.
Method selection requires that a class precedence list can be
determined for each class. This list orders the class and its superclasses
from most to least specific.
The hierarchical relationships among
the Common Lisp types are maintained by the classes corresponding to
those types. Thus the existing type hierarchy is used for determining
the class precedence lists for each class that corresponds to
a predefined Common Lisp type.
In some cases, {\it Common Lisp: The
Language\/} does not specify a subtype/supertype relationship for two
supertypes of a given type. For example, {\bf null} is a subtype of
both {\bf symbol} and {\bf list}, but {\it Common Lisp: The Language\/}
does not specify whether {\bf symbol} is more or less specific than {\bf
list}. The \CLOS\ specification defines those relationships for all
such classes.
The following table lists the set of classes that correspond to
predefined Common Lisp types required by
\CLOS. The superclasses of each such class are presented in
order from most specific to most general, according to the class precedence
list for the class.
\boxfig
{\dimen0=.75pc
\tabskip \dimen0 plus .5 fil
\halign to \hsize {#\hfil\tabskip \dimen0 plus 1fil\hfil\tabskip \dimen0 plus .5 fil&\hfil\cr %was &
\noalign{\vskip -9pt}
\hfil\bf Class&\bf Class Precedence List\span\omit\span\omit\cr
\noalign{\vskip 2pt\hrule\vskip 2pt}
array&t\cr
bit-vector&vector, array, sequence, t\cr
character&t\cr
complex&number, t\cr
cons&list, sequence, t\cr
float&number, t\cr
integer&rational, number, t\cr
list&sequence, t \cr
null&symbol, list, sequence, t\cr
number&t\cr
ratio&rational, number, t\cr
rational&number, t\cr
sequence&t\cr
string&vector, array, sequence, t\cr
symbol&t\cr
t\cr
vector&array, sequence, t\cr
\noalign{\vskip -9pt}
}}
\caption{}
\endfig
Individual implementations can allow other type specifiers to have a
corresponding class. Individual implementations can also add additional
subclass relationships and can add additional elements to the class
precedence lists in the above table,
as long as they do not violate the type
relationships and disjointness requirements
specified by {\it Common Lisp: The Language\/}.
However, individual implementations are not free to add subclass
relationships involving user-defined standard classes.
This subsection on page 1-34 is replaced as follows:
\beginsubSection{Standard Metaclasses}
The \CLOS\ provides a number of predefined metaclasses. These
include the following: {\bf standard-class},
{\bf built-in-class}, and {\bf structure-class}.
% funcallable-class?
\beginlist
\item{\bull}
The class {\bf standard-class} is the default class of classes defined
by {\bf defclass}.
\item{\bull} The class {\bf built-in-class} is the class of classes
that have special implementations with restricted capabilities.
All classes that correspond to the standard Common Lisp types
specified in {\it Common Lisp: The Language\/} by Guy L. Steele Jr.
are potentially instances of {\bf built-in-class} or a subclass
of {\bf built-in-class}.
%These types are listed in Figure~1-1.
It is implementation-dependent whether each of these classes
is actually built-in.
\item{\bull}
All classes defined by means of {\bf defstruct} are instances of
{\bf structure-class} or a subclass of {\bf structure-class}.
The class {\bf structure-class} is potentially a subclass
of {\bf built-in-class}.
\endlist
\endsubSection%{Standard Metaclasses}
∂30-Oct-87 0809 Common-Lisp-Object-System-mailer Re: standard type class
Received: from SCORE.STANFORD.EDU by SAIL.STANFORD.EDU with TCP; 30 Oct 87 08:09:46 PST
Received: from hplabs.HP.COM (hplabs.hpl.hp.com.#Internet) by SCORE.STANFORD.EDU with TCP; Fri 30 Oct 87 08:06:14-PST
Received: from hplms2 by hplabs.HP.COM with SMTP ; Fri, 30 Oct 87 08:07:23 PST
Received: from hplabsz.hpl.hp.com by hplms2; Fri, 30 Oct 87 08:07:06 pst
Return-Path: <kempf@hplabsz>
Received: from hplabsz by hplabsz; Fri, 30 Oct 87 09:06:40 pst
To: "David A. Moon" <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Cc: Common-Lisp-Object-System@SAIL.STANFORD.EDU
Subject: Re: standard type class
X-Mailer: mh6.5
In-Reply-To: Your message of Fri, 30 Oct 87 00:48:00 -0500.
<19871030054823.6.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Fri, 30 Oct 87 08:06:37 PST
Message-Id: <3610.562608397@hplabsz>
From: kempf%hplabsz@hplabs.HP.COM
> Suggestion:
> - eliminate the term "standard type class"
> - when we mean "a class that corresponds to a predefined Common
> Lisp type" we should say exactly that, no need to abbreviate.
> - rename the standard-type-class metaclass to built-in-class,
> and clarify that it is implementation-dependent whether any
> potentially built-in class is in fact built-in and has this
> metaclass.
> - clarify the requirements on portable programs
These suggestions and the accompanying draft appear to clarify the built
in class section.
jak
∂30-Oct-87 0858 Common-Lisp-Object-System-mailer Re: Some open issues
Received: from RELAY.CS.NET by SAIL.STANFORD.EDU with TCP; 30 Oct 87 08:58:04 PST
Received: from relay2.cs.net by RELAY.CS.NET id ad09175; 30 Oct 87 9:35 EST
Received: from csl.ti.com by RELAY.CS.NET id ag03690; 30 Oct 87 9:32 EST
Received: from Jenner by tilde id AA15111; Fri, 30 Oct 87 07:32:41 CST
Message-Id: <2771588021-5091608@Jenner>
Date: Fri, 30 Oct 87 07:33:41 CST
From: Patrick H Dussud <DUSSUD%jenner.csc.ti.com@RELAY.CS.NET>
To: "David A. Moon" <Moon@SCRC-STONY-BROOK.ARPA>
Cc: Common-Lisp-Object-System@SAIL.STANFORD.EDU
Subject: Re: Some open issues
In-Reply-To: Msg of Thu, 29 Oct 87 15:59 EST from "David A. Moon" <Moon@scrc-stony-brook.arpa>
Date: Thu, 29 Oct 87 15:59 EST
From: "David A. Moon" <Moon@scrc-stony-brook.arpa>
Subject: Re: Some open issues
Date: Thu, 29 Oct 87 08:44:13 CST
From: Patrick H Dussud <DUSSUD%jenner.csc.ti.com@RELAY.CS.NET>
We said at the Palo Alto meeting (If I remember correctly) that something like
(defmethod foo ((a c1) (b c2) &key x )
...)
would result into a method which lambda list is ((a c1) (b c2) &key x)
(used for the lambda-list congruence computation),
and a function which lambda list can be (a b &key x &allow-other-keys).
It is done so because the generic function check the keywords arguments,
not the method.
If what I said is correct,
It is.
the question is: When do we change/generate the
function's lambda list? Do we generate the final one during the
macroexpansion of DEFMETHOD or do we change the lambda-list during the
execution of (make-instance 'standard-method ...)?
It has to be during the macro expansion of defmethod, since the :function
initarg to standard-method (although I don't have any documentation that
says this explicitly) can be a function that has already been compiled
and can't have its lambda-list mucked with.
I had the same opinion on this.
The documentation on 2-53, 2-54 of how to create generic functions and
methods of your own is pretty unsatisfactory. It seems like a bit too
much detail to be covering under make-instance, yet it's not really
enough detail to cover all of the issues, like what does the lambda-list
of the :function have to look like? And what about making ones own
classes? I think this stuff may have to move into chapter 3 and become
documentation sections of their own for classes standard-method,
standard-class, and standard-generic-function, rather than being
tucked inside make-instance.
I agree.
∂30-Oct-87 1422 Common-Lisp-Object-System-mailer comments on portions of the Oct 26 10:05 draft
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 30 Oct 87 14:22:23 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 268751; Fri 30-Oct-87 17:23:14 EST
Date: Fri, 30 Oct 87 17:22 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: comments on portions of the Oct 26 10:05 draft
To: Common-Lisp-Object-System@SAIL.STANFORD.EDU
Message-ID: <19871030222257.1.MOON@EUPHRATES.SCRC.Symbolics.COM>
In general the document is greatly improved and I'm fairly happy with it,
execpt for these last few points.
I've excluded comments on things that appeared to be already fixed in the
TEX source, since I was reading an unproofread draft. Also I tried to
avoid duplications others' comments.
1-10: "A subclass inherits methods in the sense that any method applicable to
an instance of a class is also applicable to instances of any subclass
of that class (all other arguments to the method being the same)."
At the beginning of the second line, should "an instance" be "all instances"
so as to avoid any questions about methods-on-individuals?
1-17: "Note that instances of standard-type classes are disjoint with all other
types."
This is wrong, type disjointness of standard-type classes is controlled
by CLtL, not by us. The previous draft said "Note that instances of
standard classes are type disjoint with all other types" and I think the
switch from standard classes to standard-type classes was an editing
error. In the "built-in-class" stuff I mailed out last night, I
included a suggested rewrite that more explicitly conveys the idea that
I think this paragraph was hinting at.
1-19 top of page: the explanation of looping precedence order is too complicated,
I don't think we really need double indices here. Can't we just say
C1 through Cn, n>=2, where each precedes the next and also Cn precedes C1?
I think trying to call Cn C2 was what complicated the notation.
1-19 last paragraph before examples: I still think this should be generalized
to cover relatively separated subgraphs whose common element is not T, as
I said in earlier comments.
1-23 2nd para:
"When a new {\bf defgeneric} form is evaluated and a generic
function of the given name already exists, the existing generic function
object is modified. This does not modify any of the methods associated
with the generic function."
except for modifications as a result of :method options in the defgeneric.
1-23 2nd bullet: "The lambda-list of the new method
must be congruent with the lambda-list of the generic function or else
an error is signaled." applies to both new and redefined methods, i.e. both
bullets, so this should not be inside the second bullet. It looks like
it and the cross-referenced to congruence should be a separate paragraph
immediately after the bullets, preceding the paragraph about what happens
when no generic function by that name already exists.
1-24: "...parameter specializers
are used in the functional interface to method creation ({\bf
make-instance} of {\bf standard-method} and {\bf get-method})." would
be more legible if it said: "...parameter specializers
are used in the functional interface to method creation ({\bf get-method}
and {\bf make-instance} of {\bf standard-method})."
1-25 first paragraph: "By convention, qualifiers are usually
symbols, but it is possible to use a vector used as a qualifier."
delete "used"
1-25 second paragraph: "When a method combination type is
defined using the short form of {\bf define-method-combination},
primary methods are defined to include not only the methods qualified
with the name of the type of method combination, but certain others as
well." Delete "not only" and "but certain others as well". The only
primary methods are the qualified ones. Add that auxiliary methods
for this case are :around methods.
1-41: the term "setf macro" is used without being defined. Adding
", defined by defsetf or define-setf-method," should be sufficient to
give the reader the idea of what we mean by "setf macro."
We might want to be a little more explicit, rather than just relying
on the example in the last bullet, about the fact that the new-value
is received by the setf function as its first argument. Also to avoid
any wondering, we could say that in a setf generic function this argument
is just as specializable as any other required argument.
∂02-Nov-87 1330 Common-Lisp-Object-System-mailer :accessor slot option
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 2 Nov 87 13:29:52 PST
Received: from Semillon.ms by ArpaGateway.ms ; 02 NOV 87 13:30:42 PST
Date: Mon, 2 Nov 87 13:30 PST
From: Gregor.pa@Xerox.COM
Subject: :accessor slot option
To: Common-Lisp-Object-System@Sail.Stanford.edu
Message-ID: <871102133014.0.GREGOR@SPIFF.isl.parc.xerox.com>
Line-fold: no
I have become uncomfortable with the :reader and :accessor slot options.
Right now, at the very least, I would like to add a :writer option, I
may also want to remove or rename the :accessor option. The :writer
option would work in the obvious way:
(defclass foo ()
((a :reader foo-a
:writer (setf foo-a))))
This would allow someone who wanted to define a writer but no reader to
do it, it also makes the mapping onto the new setf proposal more
explicit.
I agree that in cases where you want both a reader and a writer its
probably too verbose, so we probably need to keep the :accessor option,
but what if we renamed it, maybe to :reader-writer or perhaps
:accessors.
Or it may just be that re-reading that part of the spec will make me
happy.
-------
∂02-Nov-87 1417 Common-Lisp-Object-System-mailer Comments on chapter 2
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 2 Nov 87 14:17:28 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 270177; Mon 2-Nov-87 17:18:28 EST
Date: Mon, 2 Nov 87 17:18 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Comments on chapter 2
To: Common-Lisp-Object-System@SAIL.STANFORD.EDU
Message-ID: <19871102221820.9.MOON@EUPHRATES.SCRC.Symbolics.COM>
Page numbers are from the Oct 26 10:17 draft, but I've omitted comments
on things that are already fixed in the source in the latest version on SAIL.
2-10: Cross-reference to ``Changing Classes'', which has been renamed.
Example hasn't been updated yet to realize that rho is the radius and
theta is the angle.
2-11: First remarks paragraph: this could just speak of classes whose
metaclass is standard-class, without worrying about whether or not the
:metaclass option was specified, similar to the way some similar text
was fixed up in chapter 1 recently. Not edited for standard-type-class
removal yet. The phrase "After completing all other actions, {\bf
change-class} invokes the generic function {\bf class-changed}." is
somewhat unclear as to what "all other actions" are, maybe some text got
lost here. This should be improved when the business of who evaluates
the :initforms is straightened out.
2-12: Cross reference to ``Redefining Classes'' should be to
``Changing the Class of an Instance''.
2-14: Cross reference to ``Changing Classes'' should be to
``Changing the Class of an Instance''.
2-39: missing quote mark in (documentation (setf symbol) 'function).
I forget if this one was already commented upon.
2-54: under make-instance, we have
"The {\bf :function} argument is the method function.
The length of the list of specializers must be equal to
the number of required arguments of the method function, or
else an error is signaled."
Since Common Lisp doesn't require implementations to be able to
determine the number of required arguments of a function, given the
function, I don't see how this requirement to signal an error
can be implemented. We might have to make this the same less stringent
error checking that CLtL prescribes for calling a function with the
wrong number of arguments.
Also as mentioned before this section will need to discuss more about
the relations between the method lambda-list and the method function
lambda-list.
2-55: The first Purpose ("Purposes"?) sentence for make-instances-obsolete
is misleading. Not every defclass redefinition calls this, it's only
guaranteed to be called under the circumstances described on 1-13.
Also there is a conflict between the value of make-instances-obsolete
being eq to the class argument, and the class argument being allowed
to be a name of a symbol; just needs the wording cleaned up a little.
Also I'm not sure what the remark
"The generic function {\bf make-instances-obsolete} is invoked only on
classes that are instances of {\bf standard-class}."
means; does this mean the user is not allowed to invoke it on other
classes, or is this more of the statement under Purpose of when defclass
invokes this?
2-70: I think we ought to mention that the typical implementation will
compile slot-value inline, or somehow efficiently, in methods. Users need
to have some rough idea of what sort of efficiency to expect, and reading
the document the way it is right now would tend to lead the naive reader
to think that CLOS slots are much less efficient to access than defstruct
slots, whereas the intention has clearly been that there be only a minor
efficiency cost for using CLOS slots, at least in the majority of
implementations. We don't have to give the details (except maybe in the
meta-object chapter), but we ought to mention the possibility of optimization.
2-72: In the first remarks paragraph for symbol-macrolet, "expansion"
is probably supposed to be in italics. At least, I think what is intended
here is to say that the scope does not include the -expansion- forms
that are substituted for the -symbols-. At first I thought "expansion"
referred to the result of expanding the invocation of symbol-macrolet.
2-73: First sentence for update-instance-structure is missing "be".
Also this hasn't been updated yet to reflect the division of labor between
caller and primary method that has been adopted in chapter 1.
2-77: The remarks for with-added-methods still speak of modifying an existing
generic function. This needs to be rephrased in terms of defaulting the
values of these options, for the newly-created generic function, from their
values in the existing generic function.
2-79: "The macro {\bf with-slots} can be used inside a method or inside
any function." implies it can't be used at top level, but that's not what
we mean to say.
∂03-Nov-87 0801 Common-Lisp-Object-System-mailer Comment on the chapter 2.
Received: from RELAY.CS.NET by SAIL.STANFORD.EDU with TCP; 3 Nov 87 08:01:45 PST
Received: from relay2.cs.net by RELAY.CS.NET id ae02430; 3 Nov 87 10:36 EST
Received: from csl.ti.com by RELAY.CS.NET id af06989; 3 Nov 87 10:32 EST
Received: from dsg by tilde id AA24093; Tue, 3 Nov 87 08:36:00 CST
Received: From Jenner By dsg Via CHAOS-NET With CHAOS-MAIL; Tue, 3 Nov 87 08:01:35 CST
Message-Id: <2771935258-3166612@Jenner>
Date: Tue, 3 Nov 87 08:00:58 CST
From: Patrick H Dussud <DUSSUD%jenner.csc.ti.com@RELAY.CS.NET>
To: Common-Lisp-Object-System@SAIL.STANFORD.EDU
Subject: Comment on the chapter 2.
In the Oct 26 draft, page 2-65(slot-boundp), 2-67(slot-makunbound),
2-70(slot-value), in the remarks field, the call to SLOT-MISSING is
incorrect. INSTANCE must be added after (CLASS-OF INSTANCE).
Patrick.
∂03-Nov-87 1045 Common-Lisp-Object-System-mailer Comment on the chapter 2, Version of Nov 2.
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 3 Nov 87 10:45:09 PST
Received: from Cabernet.ms by ArpaGateway.ms ; 03 NOV 87 10:37:34 PST
Date: 3 Nov 87 10:29 PST
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Comment on the chapter 2, Version of Nov 2.
To: Common-Lisp-Object-System@SAIL.STANFORD.EDU
cc: Bobrow.pa@Xerox.COM
Message-ID: <871103-103734-2963@Xerox>
General Comment: Much improved again. Having method signatures makes a
big difference. I think that if there is a method signature, there
should not be a section called Syntax. They are to some extent
redundant, and where they are not, Syntax was almost always wrong.
2-8 This is the first example of the redundancy. Please take out
Syntax, and the first two sentences under Arguments. The signature
specifies what the types of the arguments must be, and if people add
another method the arguments need not be those objects.
For example, suppose someone wanted to add a method:
add-method (s symbol) (lambda-exp listp)
where s was supposed to name a generic function and lambda-exp was a
list for a function, then the statements under arguments would be
untrue.
2-9 Last sentence of third paragraph "It defines the next method ... "
--> "The standard method combination type defines the next method ... "
(I garden pathed on the "It")
2-11 The environment argument is only mentioned. There is no statement
here, or later for symbol-class, etc about what it means to have the
environment. So for example,
"(cboundp 'foo e1) returns true if foo is bound to a class IN THE
ENVIRONMENT DENOTED BY e1."
2-12 Second paragraph, first sentence should read
"If in the old class there is ANY slot of the same name as any LOCAL
slot in the new class, the value of that slot is unchanged"
Remove Syntax section, Remove first two lines of Arguments. The last
sentence should read
"... and then invokes the first method with the class returned as value
from (symbol-class symbol)."
In Remarks section, you can put the comment (if you want) about possible
extensions to objects that are not standard class. But I would just
leave it out as redundant with the introductory statement about
generic-functions being extendable.
Examples: you need an :initarg :x and :initarg :y in the defclass to
have the make-instance work on the next page.
2-13 Remarks: Second sentence "... can be used to assign values to slots
in the transformed instance."
Next paragraph: Third sentence might read better as
"The methods currently executing may no longer be applicable."
The complication of combined methods is not worth the confusion here, I
think.
2-17 Purpose: Try "... and returns a symbol. This symbol is not
guaranteed to be the name of this class. See remarks below."
Remove Syntax.
Remarks: It is possible that C /= (symbol-class(class-name C)). For
example:
(defclass foo () (a))
(defclass bar () (b))
(setq f1 (symbol-class foo))
(setq f2 (symbol-class bar))
(setf (symbol-class foo) f2)
(class-name f1) --> foo
(class-name (symbol-class 'foo)) --> bar
2-19 Purpose: "... name a class IN AN ENVIRONMENT".
Remarks: It sounds like the symbol is somehow spoiled (" the symbol is
no longer usable as the name of a type"). Why not say something like
"the symbol is no longer associated with a class that defines a type."
2-21 syntax
replace {slot-option}* by [[↑ slot-option]]
and use
{:accessor generic-function-name}*
{:reader generic-function-name}*
{:initarg name}*
as the last three items of slot-option. Then the remarks on which
options can appear more than once in Arguments are redundant.
2-22 First paragraph. "... the definition of that class is replaced FOR
INSTANCES OF STANDARD-CLASS."
2-23 para 2 "... is not allowed as an abbreviation for the syntax
(slotname :initform). THIS IS DIFFERENT THAN DEFSTRUCT."
2-24 First sentence, same as for p 2-22 " ... class is guaranteeed to be
redefined for classes that are instances of standard-class."
2-26
The syntax of defgeneric now shows a lambda-list as a required argument.
I thought :lambda-list was supposed to be a keyword argument. Similarly
for generic-labels, generic-flet, generic-function, and
with-added-methods. When there are method descriptions provided, the
lambda-list is often redundant, and hence can be a cause for mistakes.
My notes from the meeting show that there was no required lambda-list,
at least for the generic-labels, generic-flet, generic-function, and
with-added-methods. Hence by extension, there should not be a required
lambda-list in defgeneric.
2-27 "The :argument-precedence-order option has a value which is a
permutation of the list of required arguments for generic function. It
is used to specify the order in which the required arguments ... When
the :argument-precedence-order is given, then an explicit lambda-list
for the generic function must be given. ..."
Example:
(defgeneric char-to-stream
(:lambda-list (char stream &optional font))
(:argument-precedence-order (stream char)))
Is this the correct syntax, or should it be:
(defgeneric char-to-stream
(:lambda-list char stream &optional font)
(:argument-precedence-order stream char))
I don't like this as well.
2-40
Remove Syntax for describe
2-41
Remove Syntax for documentation (Here it specifies that the second
argument is optional and we cannot specialize on optional arguments).
If Common Lisp has it as optional, then the signatures must only be on
the first type, with constraints specified in English on the optional
argument.
2-43
Purpose: Remove second sentence , that is "If name does not specify a
generic function, an error is signalled."
2-44
"The keyword arguments correspond to the option arguments of defgeneric,
except that the :method-class and the :generic-function-class can be
class objects as well as names."
2-45, 2-47, 2-49 Remark about required lambda-list again.
2-55
This description of make-instance is just wrong. The signatures are
wrong (they are off a metalevel). They would be appropriate signatures
for initialize-instance It should say something like
Method Signatures:
make-instance (class standard-class) &key &rest initargs
Arguments:
The initargs arguments are explicitly checked within make-instance by
the generic function check-initargs. These initargs are the union of
the keyword arguments allowed for all applicable methods on
initialize-instance, and the :initarg options of the class.
See the section on Object Creation. For instances of particular
classes, see the description of the initialize-instance method.
---
Then if we want we can put in the remarks section on initialize-instance
the arguments that each of the initialize-instance methods take.
[[However, I would prefer to see these in Chapter 3 under the
descriptions of the classes]]
initialize-instance (class standard-class) &key :direct-superclasses
:direct-slots :options
The :direct-superclasses argument is a list of symbols (class names) or
class objects. The :direct-slots argument is a list of slot-description
objects (see chapter 3) and the :options is a list of the type accepted
by defclass as class options, except :metaclass is not allowed.
initialize-instance (gfn standard-generic-function) &key :lambda-list
...
initialize-instance (method standard-method) &key ...
2-58 Purpose (Why is this one plural?)
"... when defclass has been used to redefine an existing class WITH
METACLASS standard-class."
Remove Syntax
Arguments: The class argument is a class object whose instances are to
be made obsolete.
2-59
Next to last paragraph. "... the result is a form that calls the first
method, M1, and arranges for call-next-method to reach the next method,
M2, in the list. An invocation of call-next-method in M2 reaches the
following method, M3, and this continues through the methods in the
order they appear in method-list. If a call-next-method is invoked by
the last method in method-list, an error is signaled."
2-64
Remove Syntax. Remove comment in purpose about method on
standard-generic-function signals an error (It appears 6 lines below)
2-67 Remove syntax. Remove first two sentences of Arguments.
2-74
Again something needs to be said about relationship of name and
environment.
2-80
It needs to be said that if name is bound to a macro, then an error is
signalled.
2-82
There are quote marks that are missing around slot-entry in all calls to
slot-value.
e.g. (slot-value #:Temp 'slot-entry1)
∂03-Nov-87 1354 Common-Lisp-Object-System-mailer CLOS mailing list
Received: from UUNET.UU.NET by SAIL.STANFORD.EDU with TCP; 3 Nov 87 13:54:48 PST
Received: from mcvax.UUCP by uunet.UU.NET (5.54/1.14) with UUCP
id AA08285; Tue, 3 Nov 87 16:55:32 EST
From: mcvax!crin.crin.fr!masini@uunet.UU.NET
Received: by mcvax.cwi.nl; Tue, 3 Nov 87 22:35:56 +0100 (MET)
Received: by inria.inria.fr; Tue, 3 Nov 87 16:21:56 +0100 (MET)
Date: Tue, 3 Nov 87 16:04:18 +0200
Received: by crin.crin.fr, Tue, 3 Nov 87 16:04:18 +0200
Subject: CLOS mailing list
To: Common-Lisp-Object-System@sail.stanford.edu
Message-Id: <562946603/masini@crin.crin.fr>
We are currently making a study about Object Oriented Languages, their past,
present and future.
I've been told you were mailing news about the conception and the evolution of
CLOS. Is it possible for me to be added to your mailing list ?
Thanks in any case.
Gerald MASINI, CRIN (Centre de Recherche en Informatique de Nancy)
email: masini@crin.crin.fr
post: CRIN B.P. 239 54506 Vandoeuvre-les-Nancy Cedex FRANCE
phone: +33 83.91.21.45
∂03-Nov-87 1447 Common-Lisp-Object-System-mailer CLOS mailing list
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 3 Nov 87 14:47:12 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 271163; Tue 3-Nov-87 17:48:12 EST
Date: Tue, 3 Nov 87 17:47 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: CLOS mailing list
To: mcvax!crin.crin.fr!masini@uunet.UU.NET, masini@crin.crin.fr
cc: Common-Lisp-Object-System@SAIL.STANFORD.EDU
In-Reply-To: <562946603/masini@crin.crin.fr>
Message-ID: <19871103224748.5.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Tue, 3 Nov 87 16:04:18 +0200
From: mcvax!crin.crin.fr!masini@uunet.UU.NET
We are currently making a study about Object Oriented Languages, their past,
present and future.
I've been told you were mailing news about the conception and the evolution of
CLOS. Is it possible for me to be added to your mailing list ?
This mailing list is a working group developing a specification for a proposed
new object-oriented addition to Common Lisp. It's not really a news group.
There is heavy traffic with a great amount of detail, so I suspect this isn't
really the list you want to be on.
∂03-Nov-87 1512 Common-Lisp-Object-System-mailer Comment on the chapter 2, Version of Nov 2.
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 3 Nov 87 15:12:29 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 271203; Tue 3-Nov-87 18:13:30 EST
Date: Tue, 3 Nov 87 18:13 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Comment on the chapter 2, Version of Nov 2.
To: Common-Lisp-Object-System@SAIL.STANFORD.EDU
In-Reply-To: <871103-103734-2963@Xerox>
Message-ID: <19871103231327.6.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: 3 Nov 87 10:29 PST
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
2-21 syntax
replace {slot-option}* by [[↑ slot-option]]
and use
{:accessor generic-function-name}*
{:reader generic-function-name}*
{:initarg name}*
as the last three items of slot-option. Then the remarks on which
options can appear more than once in Arguments are redundant.
Stylistic comment: I hope we are not changing the style so that it is
impossible for a reader who skips over the BNF syntax notation to
understand the document. I think that would be most unfortunate. I'd
much rather have a little redundancy than make it necessary to
understand the fine points of this increasingly obscure notation in
order to understand the document.
2-26
The syntax of defgeneric now shows a lambda-list as a required argument.
I thought :lambda-list was supposed to be a keyword argument. Similarly
for generic-labels, generic-flet, generic-function, and
with-added-methods. When there are method descriptions provided, the
lambda-list is often redundant, and hence can be a cause for mistakes.
My notes from the meeting show that there was no required lambda-list,
at least for the generic-labels, generic-flet, generic-function, and
with-added-methods. Hence by extension, there should not be a required
lambda-list in defgeneric.
I don't think we agreed in the meeting to remove these lambda-lists. My
copies of the draft documents from the meeting show the lambda-list (along
with a bunch of other stuff) missing in the first version of some writeups,
but present in the second version that we produced after discussion and
rationalization of the syntax of all the things having to do with generic
functions. Perhaps you got mixed up on which version was newer? There are
no dates on these pages but at the meeting I wrote "old" or something
on the older ones.
More comments later, perhaps.
∂04-Nov-87 1018 Common-Lisp-Object-System-mailer Issues raised by comments on chapter 2
To: common-lisp-object-system@SAIL.Stanford.EDU
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>
This message is about the format for description of generic functions
in chapter 2. The points are made as a response to a message that Danny
sent, but no one should interpret this as picking on his comments, which
simply serve to bring some decisions to light.
Danny writes:
``I think that if there is a method signature, there
should not be a section called Syntax. They are to some extent
redundant, and where they are not, Syntax was almost always wrong.''
Hm. I should have written the class redefinition section `wrong', then we
could have eliminated that too. Renaming ``Syntax'' to ``Generic Function
Syntax'' is useful when the generic function lambda-list is important to
know - that is, when it doesn't derive from the method lambda-lists.
Think of INITIALIZE-INSTANCE. And maybe it's generally useful for people
who are populating their CLOS with additional methods.
``<Add-method> This is the first example of the redundancy. Please take out
Syntax, and the first two sentences under Arguments....''
If I do that, here's the result:
******************************************************************************
Method Signatures:
add-method (generic-function standard-generic-function) (method standard-method)
Arguments:
The lambda-list of the method function must be congruent with the
lambda-lists of all other methods associated with the generic function and
with the lambda-list of the generic function, or else an error is
signaled.
******************************************************************************
Unfortunately, there is no method function mentioned. There is a larger
liklihood that this would mean the method function of the argument passed
to {\it method}, I suppose. A rewording of this could be:
``The lambda-list of the method function of the method object passed as
{\it method} must be congruent with the lambda-lists of all other methods
associated with the generic function and with the lambda-list of the
generic function, or else an error is signaled.''
One reason to describe the arguments in English is to introduce some
simple noun phrase to use to talk about these arguments.
Danny goes on:
``The signature specifies what the types of the arguments must be, and if
people add another method the arguments need not be those objects.''
This brings up the interesting point. We have a heading called ``Purpose:''.
Linda and I spent several hours last night trying to redesign the generic
function pages, and the question of when the purpose should be written as
the purpose of the generic function and when it should be the purpose
of some method. Here is an example, again ADD-METHOD.
****************************************************************************
Purpose:
The generic function add-method adds a method to a generic function. It
destructively modifies the generic function and returns the modified
generic function as its result.
****************************************************************************
ADD-METHOD has 1 method defined. This purpose could be moved to
describe the purpose of that method. If we do that, then any additional
methods are not constrained to have any particular behavior or purpose.
For instance, ADD-METHOD when applied to 2 matrices could add them - it
is the add method, after all.
The purpose when left as a description of the generic function requires
implementors to define only methods for ADD-METHOD that satisfy that
purpose.
The spirit of object-oriented programming, I guess, states that users can
define whatever the hell they like for methods. The spirit of reasonable
abstraction states that users should be required to choose their own
random names for their random methods, leaving ADD-METHOD for methods that
add methods to generic functions.
I propose, then, that the policy of CLOS be that purpose statements be promoted
to apply to generic functions whenever feasible.
Danny writes about CHANGE-CLASS:
``Remove Syntax section, Remove first two lines of Arguments. The last
sentence should read "... and then invokes the first method with the class
returned as value from (symbol-class symbol)."''
The last sentence cannot say this unless you are imagining that the
two methods on CHANGE-CLASS are defined as follows: Use LABELS to make
two functions, one that assumes a class as its second argument and one
that assumes a symbol as its second argument. Have the second invoke
the first (as a function) with (symbol-class symbol) as its second argument.
Now take these two functions and make method objects out of them with the
usual paraphenalia and stuff them into CHANGE-CLASS using ADD-METHOD.
I don't think this is what we mean. Therefore the purpose of the
second method must say something like:
``This method invokes CHANGE-CLASS on {\it instance} and (symbol-class
{\it symbol}).''
This is particularly relevant when the spirit of object-oriented programming
encourages us to write random methods for CHANGE-CLASS, and we certainly
want those methods to get a second crack at the instance in this case.
This brings up the second general point, which is are we going to require
that a pristine CLOS have all and only the methods described in the
specification? Danny's proposed rewrite of the description of CHANGE-CLASS
implies he believes so. I tend to favor the restriction.
Currently there is a statement in the introduction to Chapter 2 that
states:
``Any implementation of the \CLOS\ is allowed to provide other methods
for the generic functions described in this chapter.''
Opinions?
-rpg-
∂04-Nov-87 1025 Common-Lisp-Object-System-mailer Lambda-list in Defgeneric
To: common-lisp-object-system@SAIL.Stanford.EDU
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>
In my notes I have the typeset version of the description of
DEFGENERIC that we discussed at the Palo Alto meeting, and there are
inked-in changes on it. The changes moved things around, but left
the lambda-list as required. I also have the hand-written notes that
Sonya, I think, took during the discussion before I produced the typeset
version and from which the typeset version was derived, and it
has the lambda-list as required.
-rpg-
∂04-Nov-87 1104 Common-Lisp-Object-System-mailer Issues raised by comments on chapter 2
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 4 Nov 87 11:04:21 PST
Received: from Semillon.ms by ArpaGateway.ms ; 04 NOV 87 10:59:02 PST
Date: Wed, 4 Nov 87 10:58 PST
From: Gregor.pa@Xerox.COM
Subject: Issues raised by comments on chapter 2
To: Dick Gabriel <RPG@SAIL.Stanford.EDU>
cc: common-lisp-object-system@SAIL.Stanford.EDU
In-Reply-To: The message of 4 Nov 87 10:18 PST from Dick Gabriel
<RPG@SAIL.Stanford.EDU>
Message-ID: <871104105832.6.GREGOR@SPIFF.isl.parc.xerox.com>
Line-fold: no
Date: 04 Nov 87 10:18 PST
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>
.
.
The spirit of object-oriented programming, I guess, states that users can
define whatever the hell they like for methods. The spirit of reasonable
abstraction states that users should be required to choose their own
random names for their random methods, leaving ADD-METHOD for methods that
add methods to generic functions.
I propose, then, that the policy of CLOS be that purpose statements be promoted
to apply to generic functions whenever feasible.
Whenever 'reasonable' is more like it. For example, the purpose of the
add-method generic function is to add a method to a generic function.
If there is already a similar method an error is signalled. The generic
function is completely updated to know about the new method.
The particular method on (standard-gf standard-method), has some of its
own private behavior as well. For example, it defines what it means for
methods to be similar in this case (same qualifiers and specializers).
It also defines what the lambda-list congruence rules will be.
So its not a matter of whenever feasible, its a matter of reasoning it
out on a case by case basis.
.
.
``Any implementation of the \CLOS\ is allowed to provide other methods
for the generic functions described in this chapter.''
I think this should be changed so that we can make this statement about
some generic functions and not others. Even in the cases where we say
its OK to have more methods we are going to want some language for
placing some restrictions on where there could be methods. For example,
in print-object, an implementation should be free to have methods on as
many of its pre-defined classes as it likes, but it should not be
allowed to define print-object methods on user-defined classes behind
said user's back.
Of course what is really causing all the problem here is that none of us
has any real idea what a 'protocol' is or how to specify one.
-------
∂04-Nov-87 1210 Common-Lisp-Object-System-mailer method signatures
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 4 Nov 87 12:09:55 PST
Received: from JUNCO.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 272050; Wed 4-Nov-87 15:10:51 EST
Date: Wed, 4 Nov 87 15:10 EST
From: Sonya E. Keene <skeene@STONY-BROOK.SCRC.Symbolics.COM>
Subject: method signatures
To: common-lisp-object-system@sail.stanford.edu
Message-ID: <19871104201026.2.SKEENE@JUNCO.SCRC.Symbolics.COM>
I like the new method signatures. They give good information in a
concise format. However, I don't believe that a Method Signature is
redundant with Syntax.
When readers look in the specification for a generic function such as
ADD-METHOD, there are two different kinds of information they might be
seeking:
How do I call this g-f?
--Answered by Syntax
What methods are guaranteed to exist for this g-f?
--Answered by Method Signature
Yes, I know that the reader can divine the answer to the first question
by looking at the Method Signature. But it takes a little bit of
parsing with your eyes, and I think we should spare our readers from
that.
Actually, the more I think about this, the more strongly I feel about
it. Here's more of my reasoning:
If we remove Syntax for all generic functions that have Method
Signatures, we are skewing our specification in a certain way. We are
essentially suggesting that users should be able to divine information
about a generic function by looking at one or more methods. But this
is entirely backwards. We should be recommending that people learn
about the generic function first, and then (if necessary) learn about
the individual methods.
∂04-Nov-87 1647 Common-Lisp-Object-System-mailer Re: Issues raised by comments on chapter 2
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 4 Nov 87 16:47:32 PST
Received: from Cabernet.ms by ArpaGateway.ms ; 04 NOV 87 16:14:31 PST
Date: 4 Nov 87 16:14 PST
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Re: Issues raised by comments on chapter 2
In-reply-to: Sonya E. Keene, Dick Gabriel
To: common-lisp-object-system@sail.stanford.edu
Message-ID: <871104-161431-2659@Xerox>
After pondering Dick's and Sonya's messages, I take back my plea for
non-redundancy (I usually favor redundancy anyway). Syntax is useful,
and I think Method Signatures should include all the arguments,
including keyword names, optionals (as they did for make-instance in the
version of Nov 2). Sonya's characterization of the different questions
answered by Syntax and Method Signatures is helpful.
How do I call this g-f?
--Answered by Syntax
What methods are guaranteed to exist for this g-f?
--Answered by Method Signature
Some other comments:
----
RPG:
One reason to describe the arguments in English is to introduce
some simple noun phrase to use to talk about these arguments.
I also agree with Dick's comment. The redundancy I found slightly
distressing was where Arguments gave type restrictions on specialized
arguments (e.g. The {\it method} argument is a method object.). I am
all in favor of English.
----
RPG:
I propose, then, that the policy of CLOS be that purpose
statements be promoted to apply to generic functions whenever
feasible.
This is the place that the contract for the genric function is
described.
---
Danny writes about CHANGE-CLASS:
``Remove Syntax section, Remove first two lines of Arguments.
The last sentence should read "... and then invokes the first
method with the class returned as value from (symbol-class
symbol)."''
Therefore the purpose of the second method must say something
like:
RPG answers:
``This method invokes CHANGE-CLASS on {\it instance} and
(symbol-class {\it symbol}).''
I agree with Dick. A much better wording of what I intended.
------
RPG:
This brings up the second general point, which is are we going
to require that a pristine CLOS have all and only the methods
described in the specification? Danny's proposed rewrite of the
description of CHANGE-CLASS implies he believes so. I tend to favor
the restriction.
I don't know what I said to generate this idea. I think I believe the
statement above.
But I don't know what criteria are appropriate. What are the criteria
for Common Lisp implementations. Must they have just the types and
functions specified in CTtL. Or is it only the using up of symbols that
count (i.e. Can an implementation have functions and types whose names
the ordinary user doesn't see?). If so, are extra methods (which don't
have names) more like types and functions whose names are in another
package, or like symbols.
For example, CLOS specifies only one method for describe. Could special
methods for describe specialized to pathnames or streams etc. be
defined. Isn't this an implemenation decision relative to putting the
code to discriminate these types in the default method, or in separate
methods?
Finally, I appreciate the spirit in which Dick wrote his response:
The points are made as a response to a message that Danny sent,
but no one should interpret this as picking on his comments, which
simply serve to bring some decisions to light.
∂04-Nov-87 1737 Common-Lisp-Object-System-mailer format for description of generic functions in chapter 2
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 4 Nov 87 17:37:06 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 272368; Wed 4-Nov-87 20:37:58 EST
Date: Wed, 4 Nov 87 20:38 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: format for description of generic functions in chapter 2
To: common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: The message of 4 Nov 87 13:18 EST from Dick Gabriel <RPG@SAIL.Stanford.EDU>,
<871104105832.6.GREGOR@SPIFF.isl.parc.xerox.com>,
<19871104201026.2.SKEENE@JUNCO.SCRC.Symbolics.COM>,
The message of 4 Nov 87 18:32 EST from Dick Gabriel <RPG@SAIL.Stanford.EDU>
File-References: SAIL.STANFORD.EDU:NEW.DVI[CLS], SCRC|S:>Moon>LSP].babyl.newest
Message-ID: <19871105013806.6.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: 04 Nov 87 1018 PST
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>
I propose, then, that the policy of CLOS be that purpose statements be promoted
to apply to generic functions whenever feasible.
I agree with that. However, the new.dvi file that is a sample of the
new format does not seem to be written that way. Lengthy comments about
this below, but first a relatively minor comment on the format.
Too much of the text in a method signature is italicized. Only the
parameter names should be italicized; the parentheses, lambda-list
keywords, and parameter specializer names should be in should be in a
roman font or a typewriter font; this would be more consistent with the
style used elsewhere.
This brings up the second general point, which is are we going to require
that a pristine CLOS have all and only the methods described in the
specification? Danny's proposed rewrite of the description of CHANGE-CLASS
implies he believes so. I tend to favor the restriction.
Currently there is a statement in the introduction to Chapter 2 that
states:
``Any implementation of the \CLOS\ is allowed to provide other methods
for the generic functions described in this chapter.''
Opinions?
I don't think we can reasonably restrict implementations from defining
other methods. Such a restriction would be inutile in any case, since
CLOS programs are obviously allowed to define other methods, and we want
to allow multiple programs to coexist in the same Lisp. Thus any program
that assumes that only the methods defined in this chapter exist is not
going to be a good citizen of the Lisp world. However, what we can say
is something like only the standard methods will be applicable to standard
objects; I think that is not precisely what I mean, but something along
those lines; the intent is that you can add new methods to extend the
behavior of the functions, but you're not supposed to break the behavior
of existing methods.
Date: Wed, 4 Nov 87 10:58 PST
From: Gregor.pa@Xerox.COM
For example,
in print-object, an implementation should be free to have methods on as
many of its pre-defined classes as it likes, but it should not be
allowed to define print-object methods on user-defined classes behind
said user's back.
Yes, that expresses it pretty well.
Date: 04 Nov 87 10:18 PST
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>
I propose, then, that the policy of CLOS be that purpose statements be promoted
to apply to generic functions whenever feasible.
Whenever 'reasonable' is more like it. For example, the purpose of the
add-method generic function is to add a method to a generic function.
If there is already a similar method an error is signalled. The generic
function is completely updated to know about the new method.
The particular method on (standard-gf standard-method), has some of its
own private behavior as well. For example, it defines what it means for
methods to be similar in this case (same qualifiers and specializers).
It also defines what the lambda-list congruence rules will be.
So its not a matter of whenever feasible, its a matter of reasoning it
out on a case by case basis.
I agree with this. The new.dvi writeup for add-method isn't written this
way, though. More about this below.
Actually, I disagree with one detail of what Gregor said. I can't understand
why lambda-list congruence should be restricted to standard generic functions
and standard methods. To me lambda-list congruence seems equally applicable
to all generic functions and methods, and furthermore it's hard to see how
generic functions could work or users could call them if there wasn't
lambda-list congruence. Thus I think congruence is part of the contract of
add-method, and should not be demoted to association with a particular method.
Date: Wed, 4 Nov 87 15:10 EST
From: Sonya E. Keene <skeene@STONY-BROOK.SCRC.Symbolics.COM>
I like the new method signatures. They give good information in a
concise format. However, I don't believe that a Method Signature is
redundant with Syntax.
I agree. I think the new.dvi format addresses this pretty well.
We should be recommending that people learn
about the generic function first, and then (if necessary) learn about
the individual methods.
I agree 100% and I think the new.dvi format is deficient in this respect.
More about this below.
Date: 04 Nov 87 1532 PST
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>
The general format is to start the page with a description of what
the generic function syntax, the method signatures of all methods
specified, the purpose of the generic function, its values, and
remarks about it. The reader should be able to look at the top 4 inches
of a function page and see the generic function lambda list and the
method signatures.
Then there is a line that separates the generic function material from
the method descriptions. Each method description repeats the signature,
adds any method-specific purpose, values, remarks etc.
This sounds very good to me, but the actual file doesn't seem to do it
precisely this way. In particular, the values and remarks are
frequently associated with a particular method where they should be
associated with the generic function as a whole. To me, values have the
same status as arguments, both are part of the interface that the
generic function contracts to supply, and which all methods must conform
to. Sometimes there will be additional method-specific things to say
about arguments or values, and then the method can have one or both of
those fields, but the generic function should always have the arguments
and values fields, and I think the normal case will be that only the
generic function will have these fields.
Another problem is with ordering of fields. In several cases, method
descriptions intervene between two parts of the generic function
description. Often the remarks and the examples come after the methods.
I think this is wrong, especially in light of Sonya's last comment
above; I think the methods should always be at the end, with nothing
after them except the See also field.
Here are some comments on specific pages of the sample new format,
and then I'll address what I think is the general problem with this
new format.
add-method has too much in the method section and not enough in the
generic-function section. In fact I don't think there is anything
to be said about the method specifically; everything that is there
now is the contract of the generic function as a whole, to which all
methods must conform. Gregor disagrees with me about the congruence
part, but not the rest of it.
change-class: the second remarks paragraph is a remark about the
generic function as a whole, and has nothing to do with the specific
method to which it is attached. The first remarks paragraph, in
contrast, applies just to this method, although I think it's
important for the generic function as a whole to undertake to call
class-changed; the only need for a method-specific remark about
class-changed is to document exactly when class-changed is called
by that particular method. Maybe that detailed remark is unnecessary?
class-changed: I feel this page is an example of good organization, much
better than the other pages. The division between generic-function and
method is exactly right.
class-name: I think the method signature is wrong; surely class-name
works on all classes, not just standard ones. Surely
(class-name (class-of (cons 1 2))) returns something, even though
we don't guarantee that it returns the symbol CONS in all implementations
(it could be the name of an implementation-dependent subclass of CONS).
describe: again I think the method signatures are wrong. What we require
is that there be an applicable method for every object that exists, not
that there be a method on the class T. I complained about this before
when it was in English, I think, and I'm complaining about it again when
it's in method signatures. This started as a typo and now is turning into
an explicit specification. I also don't think we want to require that a
method exist for the exact class standard-object, although I feel less
strongly about that. In the cases of describe and print-object, I think
no method signatures should be listed, and then we should say that the
implementation provides enough predefined methods to assure that there
is always an applicable method, but we do not standardize the precise
parameter specializers of these methods. If we do anything else we
are dictating how the PRINT function is modularized, which is not our
business.
describe: the documentation of the methods here is useless. I suggest
that the format should permit omission of documentation of methods when
the documentation wouldn't say anything.
Here's the big problem with this new breakout of methods and generic
functions: We are uncovering a significant amount of confusion about
what is the contract of a generic function, versus what is a property
of particular methods for that generic function. In effect all of
the issues and uncertainties surrounding meta-objects have suddenly
leaked into the part of the document that we thought was almost
finished. I'm really opposed to that because I think it sets us back
a long way. It's really not necessary to resolve all those issues
to get something that is entirely useful to someone who is just going
to call these generic functions and not define new methods for them.
On the other hand, I do think the introduction of the method signatures
was a good idea, and I think the format as described in the quotation
from RPG above is a good idea. If we can keep the documentation in the
style of the sample class-changed writeup, I'll be happy with the new
format, but if we're going to get bogged down in all these modularity
issues, I want no part of it.
∂04-Nov-87 2046 Common-Lisp-Object-System-mailer Re: Comment on the chapter 2, Version of Nov 2.
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 4 Nov 87 20:45:57 PST
Received: from Cabernet.ms by ArpaGateway.ms ; 04 NOV 87 18:05:58 PST
Date: 4 Nov 87 18:05 PST
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Re: Comment on the chapter 2, Version of Nov 2.
In-reply-to: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>'s
message of Tue, 3 Nov 87 18:13 EST
To: Moon@STONY-BROOK.SCRC.Symbolics.COM
cc: Common-Lisp-Object-System@SAIL.STANFORD.EDU
Message-ID: <871104-180558-2820@Xerox>
Date: 3 Nov 87 10:29 PST From: Danny Bobrow
<Bobrow.pa@Xerox.COM>
2-21 syntax replace {slot-option}* by [[↑ slot-option]]
and use {:accessor generic-function-name}* {:reader
generic-function-name}* {:initarg name}*
as the last three items of slot-option. Then the
remarks on which options can appear more than once in Arguments
are redundant.
Stylistic comment: I hope we are not changing the style so that
it is impossible for a reader who skips over the BNF syntax
notation to understand the document. I think that would be most
unfortunate. I'd much rather have a little redundancy than make it
necessary to understand the fine points of this increasingly
obscure notation in order to understand the document.
I agree. I just wanted to make the syntax be complete.
2-26 The syntax of defgeneric now shows a lambda-list
as a required argument. I thought :lambda-list was supposed to
be a keyword argument. Similarly for generic-labels,
generic-flet, generic-function, and with-added-methods. When
there are method descriptions provided, the lambda-list is
often redundant, and hence can be a cause for mistakes. My
notes from the meeting show that there was no required
lambda-list, at least for the generic-labels, generic-flet,
generic-function, and with-added-methods. Hence by extension,
there should not be a required lambda-list in defgeneric.
I don't think we agreed in the meeting to remove these
lambda-lists. My copies of the draft documents from the meeting
show the lambda-list (along with a bunch of other stuff) missing in
the first version of some writeups, but present in the second
version that we produced after discussion and rationalization of
the syntax of all the things having to do with generic functions.
Perhaps you got mixed up on which version was newer? There are no
dates on these pages but at the meeting I wrote "old" or something
on the older ones.
You are probably right about the cause for the mixup. But the issue
remains whether lambda-list should be required. For most uses of these
forms, I can't see really wanting a lambda-list e.g. just
(ensure-generic-function 'foo) followed by defmethods, or where one has
the methods for a generic-flet (etc) and hence doesn't need the
lambda-list unless the :argument-precedence-order option is used. I
still can't remember an argument for making it required. Can you remind
me please.
∂05-Nov-87 0919 Common-Lisp-Object-System-mailer lambda-list in defgeneric
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 5 Nov 87 09:19:02 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 272759; Thu 5-Nov-87 12:19:47 EST
Date: Thu, 5 Nov 87 12:20 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: lambda-list in defgeneric
To: Danny Bobrow <Bobrow.pa@Xerox.COM>
cc: Common-Lisp-Object-System@SAIL.STANFORD.EDU
In-Reply-To: <871104-180558-2820@Xerox>
Message-ID: <19871105172001.2.MOON@EUPHRATES.SCRC.Symbolics.COM>
Line-fold: No
I'll try a one-word answer, and if that doesn't work, I'll try to
find the time to write a detialed explanation.
&key.
∂05-Nov-87 0924 Common-Lisp-Object-System-mailer lambda-list in defgeneric, generic-flet, etc.
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 5 Nov 87 09:24:51 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 272765; Thu 5-Nov-87 12:25:42 EST
Date: Thu, 5 Nov 87 12:25 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: lambda-list in defgeneric, generic-flet, etc.
To: Danny Bobrow <Bobrow.pa@Xerox.COM>
cc: Common-Lisp-Object-System@SAIL.STANFORD.EDU
In-Reply-To: <871104-180558-2820@Xerox>
Supersedes: <19871105172001.2.MOON@EUPHRATES.SCRC.Symbolics.COM>
Message-ID: <19871105172557.3.MOON@EUPHRATES.SCRC.Symbolics.COM>
Line-fold: No
Never mind the one-word answer.
It's clear that the lambda-list is needed sometimes. It's needed for
&key, it's needed for :argument-precedence-order, and it's needed when
no methods are specified. It's also needed if the lambda-list serves
as documentation and the most appropriate and explanatory parameter names
are different for the generic function than for the method.
The question is whether to allow the lambda-list to be omitted in some
cases.
You seem to be concerned about the redundancy when there is exactly one
method specified. Obviously if there are no methods there is no redundant
lambda-list, and if there is more than one method specified in the
defgeneric or generic-flet or what have you, there is redundancy anyway.
My feeling is that making the syntax more cumbersome and less consistent,
by making the lambda-list optional, in order to eliminate this tiny bit of
redundancy, is not worthwhile. Also I think the redundancy can be justified
as a valuable sanity check.
Another interesting piece of experience is that the syntax of :method in
defgeneric in Flavors tries to avoid such redundancy. It has a lambda-list
for the defgeneric, but no lambda-list for the methods, just a parameter
specializer name (to use CLOS terminology). I think that experience with
this has shown that it was a bad idea and that it would have been better to
have the redundancy for the sake of a more consistent syntax.
∂05-Nov-87 0950 Common-Lisp-Object-System-mailer format for description of generic functions in chapter 2
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 5 Nov 87 09:50:35 PST
Received: from Semillon.ms by ArpaGateway.ms ; 05 NOV 87 09:44:49 PST
Date: Thu, 5 Nov 87 09:44 PST
From: Gregor.PA@Xerox.COM, Bobrow.PA@Xerox.COM
Sender: Gregor.pa@GRAPEVINE.isl.parc.xerox.com
Subject: format for description of generic functions in chapter 2
To: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
cc: common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: <19871105013806.6.MOON@EUPHRATES.SCRC.Symbolics.COM>
File-References: DOMAIN|SAIL.STANFORD.EDU:NEW.DVI[CLS],
SCRC|S:>Moon>LSP].babyl.newest
Message-ID: <871105094413.1.GREGOR@SPIFF.isl.parc.xerox.com>
Line-fold: no
Date: Wed, 4 Nov 87 20:38 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
First off, we want to say that we think the new method signature stuff
is a good idea and looks good overall.
Too much of the text in a method signature is italicized. Only the
parameter names should be italicized; the parentheses, lambda-list
keywords, and parameter specializer names should be in should be in a
roman font or a typewriter font; this would be more consistent with the
style used elsewhere.
Right.
I don't think we can reasonably restrict implementations from defining
other methods. Such a restriction would be inutile in any case, since
CLOS programs are obviously allowed to define other methods, and we want
to allow multiple programs to coexist in the same Lisp. Thus any program
that assumes that only the methods defined in this chapter exist is not
going to be a good citizen of the Lisp world. However, what we can say
is something like only the standard methods will be applicable to standard
objects; I think that is not precisely what I mean, but something along
those lines; the intent is that you can add new methods to extend the
behavior of the functions, but you're not supposed to break the behavior
of existing methods.
Right, this is hard to word, but we are going to have to make some stab
at it. We will try to take a stab at this later.
Date: Wed, 4 Nov 87 10:58 PST
Actually, I disagree with one detail of what Gregor said. I can't understand
why lambda-list congruence should be restricted to standard generic functions
and standard methods. To me lambda-list congruence seems equally applicable
to all generic functions and methods, and furthermore it's hard to see how
generic functions could work or users could call them if there wasn't
lambda-list congruence. Thus I think congruence is part of the contract of
add-method, and should not be demoted to association with a
particular method.
I (Gregor) still disagree with you about this. More in a separate
message.
This sounds very good to me, but the actual file doesn't seem to do it
precisely this way. In particular, the values and remarks are
frequently associated with a particular method where they should be
associated with the generic function as a whole. To me, values have the
same status as arguments, both are part of the interface that the
generic function contracts to supply, and which all methods must conform
to. Sometimes there will be additional method-specific things to say
about arguments or values, and then the method can have one or both of
those fields, but the generic function should always have the arguments
and values fields, and I think the normal case will be that only the
generic function will have these fields.
Another problem is with ordering of fields. In several cases, method
descriptions intervene between two parts of the generic function
description. Often the remarks and the examples come after the methods.
I think this is wrong, especially in light of Sonya's last comment
above; I think the methods should always be at the end, with nothing
after them except the See also field.
Right.
Here are some comments on specific pages of the sample new format,
and then I'll address what I think is the general problem with this
new format.
add-method has too much in the method section and not enough in the
generic-function section. In fact I don't think there is anything
to be said about the method specifically; everything that is there
now is the contract of the generic function as a whole, to which all
methods must conform. Gregor disagrees with me about the congruence
part, but not the rest of it.
Not exactly. We think both the second paragraph of the arguments
section and the second paragraph of the remarks section should be put
under method remarks. Briefly, the point is that a user should be free
to define a new kind of method that say doesn't have qualifiers or a new
kind of generic function which uses different congruence rules.
The value returned should be in the generic function, its has to be eq
to the first argument.
change-class: the second remarks paragraph is a remark about the
generic function as a whole, and has nothing to do with the specific
method to which it is attached.
Right
The first remarks paragraph, in
contrast, applies just to this method, although I think it's
important for the generic function as a whole to undertake to call
class-changed; the only need for a method-specific remark about
class-changed is to document exactly when class-changed is called
by that particular method.
Right
Maybe that detailed remark is unnecessary?
It is needed
class-changed: I feel this page is an example of good organization, much
better than the other pages. The division between generic-function and
method is exactly right.
Right
class-name: I think the method signature is wrong; surely class-name
works on all classes, not just standard ones. Surely
(class-name (class-of (cons 1 2))) returns something, even though
we don't guarantee that it returns the symbol CONS in all implementations
(it could be the name of an implementation-dependent subclass of
CONS).
In the current meta object draft, all those classes are (believe it or
not), subclasses of standard class. So, this is right according to
that. We had a long discussion with Pierre Cointe about this, that is
included in the meta-object draft we are (finally) writing.
describe: again I think the method signatures are wrong. What we require
is that there be an applicable method for every object that exists, not
that there be a method on the class T. I complained about this before
when it was in English, I think, and I'm complaining about it again when
it's in method signatures. This started as a typo and now is turning into
an explicit specification. I also don't think we want to require that a
method exist for the exact class standard-object, although I feel less
strongly about that. In the cases of describe and print-object, I think
no method signatures should be listed, and then we should say that the
implementation provides enough predefined methods to assure that there
is always an applicable method, but we do not standardize the precise
parameter specializers of these methods. If we do anything else we
are dictating how the PRINT function is modularized, which is not our
business.
describe: the documentation of the methods here is useless. I suggest
that the format should permit omission of documentation of methods when
the documentation wouldn't say anything.
Right, Right, Right...
Here's the big problem with this new breakout of methods and generic
functions: We are uncovering a significant amount of confusion about
what is the contract of a generic function, versus what is a property
of particular methods for that generic function. In effect all of
the issues and uncertainties surrounding meta-objects have suddenly
leaked into the part of the document that we thought was almost
finished. I'm really opposed to that because I think it sets us back
a long way. It's really not necessary to resolve all those issues
to get something that is entirely useful to someone who is just going
to call these generic functions and not define new methods for them.
On the other hand, I do think the introduction of the method signatures
was a good idea, and I think the format as described in the quotation
from RPG above is a good idea. If we can keep the documentation in the
style of the sample class-changed writeup, I'll be happy with the new
format, but if we're going to get bogged down in all these modularity
issues, I want no part of it.
Its true that this new breakout causes us to confront some meta-object
stuff which we don't really want to have to work out in the next 5 days.
But, it may be alright if we just take our best stab at it and then fix
it up later. Here's why. We believe that for the time being, the only
kind of programming we are really sanctioning is programming that calls
these generic functions (in cases like add-method). In these cases, we
should take our best shot, but if in the course of writing the meta spec
we decide we need to move something from method to gf or vice versa we
can. Because as far as the user who just calls generic functions like
add-method, the behavior of the generic function as a whole will be
unchanged. As a point of strategy, where we are unsure, behavior should
be ascribed to the generic function rather than the one of the methods.
Generic functions like describe and print-object are different, these we
have to try and get right this go around. Thats probably tractable,
Moon's comments above seem to hit it on the nose.
-------
∂05-Nov-87 1231 Common-Lisp-Object-System-mailer ambiguity in defgeneric and method descriptions
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 5 Nov 87 12:30:32 PST
Received: from JUNCO.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 272978; Thu 5-Nov-87 15:31:19 EST
Date: Thu, 5 Nov 87 15:31 EST
From: Sonya E. Keene <skeene@STONY-BROOK.SCRC.Symbolics.COM>
Subject: ambiguity in defgeneric and method descriptions
To: common-lisp-object-system@SAIL.STANFORD.EDU
Message-ID: <19871105203106.7.SKEENE@JUNCO.SCRC.Symbolics.COM>
Page 2-29: the defgeneric section, the first two paragraphs under
Remarks:
The first paragraph is:
"If a method already exists on the given generic function with the same
parameter specializers and the same qualifers, defgeneric replaces the
existing method with the one now being defined."
My question is, "the same as what?" I suggest clarifying it along these
lines:
"If a method already exists on the given generic function with the same
parameter specializers and the same qualifers as any method description
given in this defgeneric form, that existing method is replaced with the
one now being defined."
The second paragraph is:
"If ano method descriptions are specified and a generic function of the
same name does not already exist, a generic function with no methds is
created."
That makes perfect sense, but I think it brings up another point to
clarify. What happens if no method descriptions are specified in this
defgeneric, but there is an existing generic function with methods?
Have we decided what happens then? I don't remember any discussion
about it.
In the old days of defgeneric (before method descriptions), we said that
no methods were affected when a generic function was redefined. If
that still holds in the current scheme, the users might be faced with an
interesting pitfall. If the old defgeneric included a method
description and the new one doesn't, then the Lisp world will contain a
method, but there won't be any source of that method.
The alternative would be to follow the model of defclass; if the old
defclass defined readers or accessors and the new defclass does not,
during the redefinition those old methods and generic functions go away.
We could make old methods that were defined by the :method option to
defgeneric go away, if the new defgeneric doesn't define those methods.
Whichever one is right, it's worth another Remark.
∂05-Nov-87 1545 Common-Lisp-Object-System-mailer Re: lambda-list in defgeneric, generic-flet, etc.
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 5 Nov 87 15:44:53 PST
Received: from Cabernet.ms by ArpaGateway.ms ; 05 NOV 87 15:38:10 PST
Date: 5 Nov 87 15:37 PST
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Re: lambda-list in defgeneric, generic-flet, etc.
In-reply-to: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>'s
message of Thu, 5 Nov 87 12:25 EST
To: Moon@STONY-BROOK.SCRC.Symbolics.COM
cc: Bobrow.pa@Xerox.COM, Common-Lisp-Object-System@SAIL.STANFORD.EDU
Message-ID: <871105-153810-1563@Xerox>
Thank you for the longer answer. I find the arguments convincing enough
(that is enough to stop arguing). I am convinced now that it is SMOT
(small matter of taste), and with you, Dick and Gregor agreeing, my
taste buds must be off.
danny
∂05-Nov-87 1623 Common-Lisp-Object-System-mailer Re: ambiguity in defgeneric and method descriptions
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 5 Nov 87 16:23:10 PST
Received: from Cabernet.ms by ArpaGateway.ms ; 05 NOV 87 16:18:32 PST
Date: 5 Nov 87 16:18 PST
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Re: ambiguity in defgeneric and method descriptions
In-reply-to: Sonya E. Keene <skeene@STONY-BROOK.SCRC.Symbolics.COM>'s
message of Thu, 5 Nov 87 15:31 EST
To: skeene@STONY-BROOK.SCRC.Symbolics.COM
cc: common-lisp-object-system@SAIL.STANFORD.EDU
Message-ID: <871105-161832-1644@Xerox>
That makes perfect sense, but I think it brings up another
point to clarify. What happens if no method descriptions are
specified in this defgeneric, but there is an existing generic
function with methods? Have we decided what happens then? I don't
remember any discussion about it.
In the old days of defgeneric (before method descriptions), we
said that no methods were affected when a generic function was
redefined. If that still holds in the current scheme, the users
might be faced with an interesting pitfall. If the old
defgeneric included a method description and the new one doesn't,
then the Lisp world will contain a method, but there won't be any
source of that method.
The alternative would be to follow the model of defclass; if
the old defclass defined readers or accessors and the new defclass
does not, during the redefinition those old methods and generic
functions go away. We could make old methods that were defined by
the :method option to defgeneric go away, if the new defgeneric
doesn't define those methods.
Whichever one is right, it's worth another Remark.
I think that it is important thatold methods stay around. Consider two
applications that define a generic function. They are designed to work
independently, and also together. Hence each will have a defgeneric
(compatible of course, since they were meant to work together), and each
will independently define methods, say with their :method options. The
fact the the second one does not have the same methods as the first
should not invalidate the first, I think. The model I have is that
defgeneric updates the generic function with respect to its metaclass,
method class, etc. but does not affect existing methods. An error is
signalled for any compatibility problem of course. This is the same as
the old model. As you can see in some cases there are sources for the
other methods, and in others not (what happens now when you simply edit
a file to remove a defmethod or defun form?)
danny
∂05-Nov-87 1631 Common-Lisp-Object-System-mailer State of Affairs
To: common-lisp-object-system@SAIL.Stanford.EDU
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>
I've completed the major pass on chapter 1 that Gregor's comments
required. The result so cleaned it up that I made a second major
pass and I now believe chapter 1 to be very close to complete.
The state of affairs with chapter 2 now greatly concerns me.
To illustrate this, let me comment on one of the comments that Moon
made about the selected function pages that we put out for comment.
Regarding CHANGE-CLASS Moon writes:
``change-class: the second remarks paragraph is a remark about the
generic function as a whole, and has nothing to do with the specific
method to which it is attached.''
That remarks paragraph states:
``This method on {\bf change-class} has several semantic difficulties.
First, it performs a destructive operation that can be invoked within a
method on an instance that was used to select that method. When multiple
methods are involved because methods are being combined,
the methods currently executing or about to be executed
may no longer be applicable. Second, some implementations might use compiler
optimizations of slot access, and when the class of an instance is
changed the assumptions the compiler made might be violated.
This implies that a programmer must not use this method on {\bf
change-class} inside a method if any methods for that generic function
access any slots, or else the results are undefined.''
The semantic problem is that the class of the instance is altered while
the generic function is operating. One can argue that this is a change of
identity in some semantic domain. The fact that this is related to a
``destructive operation'' depends on the representation of the instance,
which depends on its metaclass which depends on the fact that the instance
is an instance of standard-object, because its class is standard-class.
This appears to be something specific to this method or constellation of
methods. The same reasoning holds for the mention of the compiler messing
around with optimizations of slot access - I've heard some metaclasses
say ``what's a slot?''
Therefore, the semantic difficulty is best expressed in both places:
There is a semantic difficulty with the generic function because we choose
to specify that whatever else it does it alters the class of an instance.
And this can happen in the middle of a method combination that might
involve running those other methods on a now-non-applicable instance.
This method happens to compound the problem by messing with the
representation in some way, invalidating the compiler's assumptions.
Therefore, the comment Moon makes serves to raise a much harder issue of
how close to the bone we cut our distinctions.
Notice that LGD and I gave this some amount of thought, because the
Purpose entry for the generic function states that the generic function
changes the class, while the one for this main method talks about the
destructiveness of the operation.
What has to be pointed out is that even if we choose to back out of
any changes made to the format of chapter 2 in the last 4 days (this amounts
to little or no work), we now know that the wording that we have been using
is very imprecise with respect to a level of precision to which we could
rationally aspire. This Remark, if left in a version of chapter 2 with
the older format, mixes up the general activities and meaning of a very
abstract entity (a generic function) with the activities and meaning of
a specific method.
Let me state at this point that LGD and I have neither interest nor motivation
to want to take a shot at sorting this out by ourselves. And I can easily
see this group, even in a face-to-face meeting, arguing for weeks about
the wording and exact breakdown of what is said when and where.
What's worse, our selection procedure was to pick the first 4 or 5
function pages in chapter 2 to try, not the hardest 4 or 5, and I'm not
sure that we could totally resolve CHANGE-CLASS in under 4 days of
discussion at the current bandwidth.
Therefore, I leave it to you folks to decide how to proceed.
-rpg-
∂05-Nov-87 1727 Common-Lisp-Object-System-mailer Re: format for description of generic functions in chapter 2
Received: from RELAY.CS.NET by SAIL.STANFORD.EDU with TCP; 5 Nov 87 17:26:39 PST
Received: from relay2.cs.net by RELAY.CS.NET id ae08957; 5 Nov 87 16:34 EST
Received: from csl.ti.com by RELAY.CS.NET id ad24858; 5 Nov 87 16:32 EST
Received: from Jenner by tilde id AA28983; Thu, 5 Nov 87 15:08:06 CST
Message-Id: <2772133532-6702890@Jenner>
Date: Thu, 5 Nov 87 15:05:32 CST
From: Patrick H Dussud <DUSSUD%jenner.csc.ti.com@RELAY.CS.NET>
To: common-lisp-object-system@SAIL.STANFORD.EDU
Subject: Re: format for description of generic functions in chapter 2
In-Reply-To: Msg of Thu, 5 Nov 87 09:44 PST from Gregor.PA@xerox.com, Bobrow.PA@xerox.com
Actually, I disagree with one detail of what Gregor said. I can't understand
why lambda-list congruence should be restricted to standard generic functions
and standard methods. To me lambda-list congruence seems equally applicable
to all generic functions and methods, and furthermore it's hard to see how
generic functions could work or users could call them if there wasn't
lambda-list congruence. Thus I think congruence is part of the contract of
add-method, and should not be demoted to association with a
particular method.
I (Gregor) still disagree with you about this. More in a separate
message.
I will be interested in seeing what prompted Gregor to disagree. It
seems to me that it is bad if you have to know the class of a generic
function, and find out about the lambda congruence rule for this class,
in order to know that your program is calling it properly. I doubt that
you will gain much power from changing the lambda list congruence rule
and it seems that this "flexibility" will bring confusion.
Here's the big problem with this new breakout of methods and generic
functions: We are uncovering a significant amount of confusion about
what is the contract of a generic function, versus what is a property
of particular methods for that generic function. In effect all of
the issues and uncertainties surrounding meta-objects have suddenly
leaked into the part of the document that we thought was almost
finished. I'm really opposed to that because I think it sets us back
a long way. It's really not necessary to resolve all those issues
to get something that is entirely useful to someone who is just going
to call these generic functions and not define new methods for them.
On the other hand, I do think the introduction of the method signatures
was a good idea, and I think the format as described in the quotation
from RPG above is a good idea. If we can keep the documentation in the
style of the sample class-changed writeup, I'll be happy with the new
format, but if we're going to get bogged down in all these modularity
issues, I want no part of it.
Its true that this new breakout causes us to confront some meta-object
stuff which we don't really want to have to work out in the next 5 days.
But, it may be alright if we just take our best stab at it and then fix
it up later. Here's why. We believe that for the time being, the only
kind of programming we are really sanctioning is programming that calls
these generic functions (in cases like add-method). In these cases, we
should take our best shot, but if in the course of writing the meta spec
we decide we need to move something from method to gf or vice versa we
can. Because as far as the user who just calls generic functions like
add-method, the behavior of the generic function as a whole will be
unchanged. As a point of strategy, where we are unsure, behavior should
be ascribed to the generic function rather than the one of the methods.
I like this strategy. I don't have any problems with the agreement
reached in each case.
Patrick.
∂05-Nov-87 1817 Common-Lisp-Object-System-mailer CALL-NEXT-METHOD example
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 5 Nov 87 18:17:23 PST
Received: from Semillon.ms by ArpaGateway.ms ; 05 NOV 87 18:17:08 PST
Date: Thu, 5 Nov 87 18:16 PST
From: Gregor.pa@Xerox.COM
Subject: CALL-NEXT-METHOD example
To: LGD@SAIL.STANFORD.EDU
cc: Common-Lisp-Object-System@SAIL.STANFORD.EDU
Message-ID: <871105181642.6.GREGOR@SPIFF.isl.parc.xerox.com>
Line-fold: no
Here is an example which could be used for the call-next-method section.
Its somewhat of a silly example, but I believe it captures several
important points about call-next-method. Namely its basic behavior, how
it defaults the argument when no arguments are passed, that it is a true
lexical function, and that it is possible to pass it arguments,
(defmethod collect (thing) thing)
(defmethod collect ((n number))
(let ((l ()))
(dotimes (i n)
(push (call-next-method) l))
(reverse l)))
(defmethod collect ((l list))
(mapcar #'call-next-method l))
(collect 5) ==> (5 5 5 5 5)
(collect '(a b c)) ==> (A B C)
;;; But note the following erroneous use of call-next-method.
;;; This example would cause an error to be signalled because
;;; the argument which is supplied to call-next-method would
;;; cause a different set of methods to be applicable.
(collect '(1 2 3))
-------
∂05-Nov-87 1927 Common-Lisp-Object-System-mailer CALL-NEXT-METHOD example
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 5 Nov 87 19:27:14 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 273360; Thu 5-Nov-87 22:26:51 EST
Date: Thu, 5 Nov 87 22:27 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: CALL-NEXT-METHOD example
To: Gregor.pa@Xerox.COM
cc: LGD@SAIL.STANFORD.EDU, Common-Lisp-Object-System@SAIL.STANFORD.EDU
In-Reply-To: <871105181642.6.GREGOR@SPIFF.isl.parc.xerox.com>
Message-ID: <19871106032706.1.MOON@EUPHRATES.SCRC.Symbolics.COM>
Line-fold: No
Date: Thu, 5 Nov 87 18:16 PST
From: Gregor.pa@Xerox.COM
Here is an example which could be used for the call-next-method section.
Its somewhat of a silly example, but I believe it captures several
important points about call-next-method. Namely its basic behavior, how
it defaults the argument when no arguments are passed, that it is a true
lexical function, and that it is possible to pass it arguments,
(defmethod collect (thing) thing)
(defmethod collect ((n number))
(let ((l ()))
(dotimes (i n)
(push (call-next-method) l))
(reverse l)))
(defmethod collect ((l list))
(mapcar #'call-next-method l))
(collect 5) ==> (5 5 5 5 5)
(collect '(a b c)) ==> (A B C)
;;; But note the following erroneous use of call-next-method.
;;; This example would cause an error to be signalled because
;;; the argument which is supplied to call-next-method would
;;; cause a different set of methods to be applicable.
(collect '(1 2 3))
-------
I don't see why (collect '(a b c)) isn't invalid for the same
reason. The list method becomes inapplicable in the recursive call.
∂05-Nov-87 1948 Common-Lisp-Object-System-mailer Re: ambiguity in defgeneric and method descriptions
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 5 Nov 87 19:48:30 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 273383; Thu 5-Nov-87 22:48:30 EST
Date: Thu, 5 Nov 87 22:48 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: ambiguity in defgeneric and method descriptions
To: common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: <871105-161832-1644@Xerox>
Message-ID: <19871106034841.3.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: 5 Nov 87 16:18 PST
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
The alternative would be to follow the model of defclass; if
the old defclass defined readers or accessors and the new defclass
does not, during the redefinition those old methods and generic
functions go away. We could make old methods that were defined by
the :method option to defgeneric go away, if the new defgeneric
doesn't define those methods.
Whichever one is right, it's worth another Remark.
I agree that it's worth a Remark.
I think that it is important that old methods stay around. Consider two
applications that define a generic function. They are designed to work
independently, and also together. Hence each will have a defgeneric
(compatible of course, since they were meant to work together), and each
will independently define methods, say with their :method options. The
fact the the second one does not have the same methods as the first
should not invalidate the first, I think.
I have to agree with this argument, even though I feel that such a pair
of applications is poorly structured and should have a shared "definitions"
module that contains one defgeneric. Remember we're not forcing you to put
all your method definitions into :method options (except in generic-flet,
generic-labels, and generic-function).
The model I have is that
defgeneric updates the generic function with respect to its metaclass,
method class, etc. but does not affect existing methods.
Except it does affect existing methods if :method is specified, so this
argument isn't going to tell us anything about the case that Sonya
brought up. Instead we have to say: "Note, defgeneric can add methods,
and can replace methods, but never removes a method."
An error is
signalled for any compatibility problem of course. This is the same as
the old model. As you can see in some cases there are sources for the
other methods, and in others not (what happens now when you simply edit
a file to remove a defmethod or defun form?)
That depends on how smart your editor is. But surely if it understands
removing a defmethod it can understand removing a :method option from a
defgeneric.
∂05-Nov-87 2111 Common-Lisp-Object-System-mailer Chapter 1 typos.
Received: from RELAY.CS.NET by SAIL.STANFORD.EDU with TCP; 5 Nov 87 21:11:35 PST
Received: from relay2.cs.net by RELAY.CS.NET id ac10117; 5 Nov 87 17:46 EST
Received: from csl.ti.com by RELAY.CS.NET id aa25269; 5 Nov 87 17:45 EST
Received: from Jenner by tilde id AA00248; Thu, 5 Nov 87 15:57:44 CST
Message-Id: <2772136524-6882684@Jenner>
Date: Thu, 5 Nov 87 15:55:24 CST
From: Patrick H Dussud <DUSSUD%jenner.csc.ti.com@RELAY.CS.NET>
To: Common-Lisp-Object-System@SAIL.STANFORD.EDU
Subject: Chapter 1 typos.
1-12 First defclass, ) missing.
1-24 Second paragraph, "When a method combination type is defined using
the short form of DEFINE-METHOD-COMBINATION, primary methods are defined
to include not only the methods qualified with the same name of the type
of method combination, but certain others as well". This is not true.
Primary methods include only those qualified with the name of the method
combination type.
Patrick.
∂06-Nov-87 1017 Common-Lisp-Object-System-mailer Defgeneric affects methods?
To: Common-lisp-object-system@SAIL.Stanford.EDU
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>
``Except it does affect existing methods if :method is specified, so....''
Here is an issue brought up by wording problems: do you mean
that defgeneric affects the set of existing methods (such as
replacing some of them) or that defgeneric affects some individuals
because when one is ``replaced'' a method is destructively modified?
-rpg-
∂06-Nov-87 1109 Common-Lisp-Object-System-mailer CALL-NEXT-METHOD example
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 6 Nov 87 11:09:16 PST
Received: from Semillon.ms by ArpaGateway.ms ; 06 NOV 87 11:07:01 PST
Date: Fri, 6 Nov 87 11:06 PST
From: Gregor.pa@Xerox.COM
Subject: CALL-NEXT-METHOD example
To: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
cc: Gregor.pa@Xerox.COM, LGD@SAIL.STANFORD.EDU,
Common-Lisp-Object-System@SAIL.STANFORD.EDU
In-Reply-To: <19871106032706.1.MOON@EUPHRATES.SCRC.Symbolics.COM>
Message-ID: <871106110624.7.GREGOR@SPIFF.isl.parc.xerox.com>
Line-fold: no
Date: Thu, 5 Nov 87 22:27 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
I don't see why (collect '(a b c)) isn't invalid for the same
reason. The list method becomes inapplicable in the recursive call.
Oops, your right. What I spaced on at the time was that I wasn't change
the applicable set of next methods so it was OK. Should that in fact be
the rule?
If not, here is a corrected example.
(defmethod collect (thing) thing)
(defmethod collect ((n number))
(let ((l ()))
(dotimes (i n)
(push (call-next-method) l))
(reverse l)))
(defmethod collect ((l list))
(mapcar #'call-next-method l))
(collect 5) ==> (5 5 5 5 5)
(collect '(() () ())) ==> (() () ())
;;; But note the following erroneous use of call-next-method.
;;; This example would cause an error to be signalled because
;;; the argument which is supplied to call-next-method would
;;; cause a different set of methods to be applicable.
(collect '(1 2 3))
-------
∂06-Nov-87 1229 Common-Lisp-Object-System-mailer setf of class-name
Received: from SCRC-RIVERSIDE.ARPA by SAIL.STANFORD.EDU with TCP; 6 Nov 87 12:29:23 PST
Received: from JUNCO.SCRC.Symbolics.COM by Riverside.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 185747; Fri 6-Nov-87 15:29:00 EST
Date: Fri, 6 Nov 87 15:28 EST
From: Sonya E. Keene <skeene@STONY-BROOK.SCRC.Symbolics.COM>
Subject: setf of class-name
To: common-lisp-object-system@SAIL.STANFORD.EDU
Included-msgs: <19871023233437.7.MOON@EUPHRATES.SCRC.Symbolics.COM>,
The message of 23 Oct 87 19:34 EDT from Moon@STONY-BROOK.SCRC.Symbolics.COM,
The message of 23 Oct 87 19:34 EDT from David A. Moon
Included-References: <871023-154303-1550@Xerox>
Message-ID: <19871106202846.9.SKEENE@JUNCO.SCRC.Symbolics.COM>
As far as I know, we still believe that setf of class-name should work,
but the writeup of class-name in Chapter 2 doesn't mention this.
The following forwarded message is the last I've seen on this topic, and
it looks like both Dave and Danny believe setf of class-name belongs in
the spec.
----------------
Date: Fri, 23 Oct 87 19:34 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: More on Class names
To: Common-Lisp-Object-System@sail.stanford.edu
In-Reply-To: <871023-154303-1550@Xerox>
Date: 23 Oct 87 15:42 PDT
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
It should be stated in chapter one that a many-one association from
symbols to classes is implemented by symbol-class and (setf
symbol-class). An INDEPENDENT association from class to symbol is
maintained by class-name and (setf class-name). Neither of these setf
functions effects the other association. defclass is specified to do
both (setf symbol-class) and (setf class-name).
I agree.
∂06-Nov-87 1343 Common-Lisp-Object-System-mailer Re: Defgeneric affects methods?
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 6 Nov 87 13:43:18 PST
Received: from Cabernet.ms by ArpaGateway.ms ; 06 NOV 87 13:31:28 PST
Date: 6 Nov 87 13:31 PST
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Re: Defgeneric affects methods?
In-reply-to: Dick Gabriel <RPG@SAIL.Stanford.EDU>'s message of 06 Nov 87
10:17 PST
To: Common-lisp-object-system@SAIL.Stanford.EDU
Message-ID: <871106-133128-1483@Xerox>
``Except it does affect existing methods if :method is
specified, so....''
Here is an issue brought up by wording problems: do you mean
that defgeneric affects the set of existing methods (such as
replacing some of them) or that defgeneric affects some individuals
because when one is ``replaced'' a method is destructively modified?
I think that this is an example where documentation indirection would
pay off. Describe what happens when one evaluates a defgeneric with no
:method options, and thee is an existing generic function. No existing
methods on the existing generic function is changed.
Then state that defgeneric with :method options is equivalent to a
defgeneric with no :method options follwoed by a set of defmethods. We
have said what happens there as well. Similar methods get replaced.
∂06-Nov-87 1352 Common-Lisp-Object-System-mailer Re: Defgeneric affects methods?
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 6 Nov 87 13:52:27 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 274069; Fri 6-Nov-87 16:51:53 EST
Date: Fri, 6 Nov 87 16:52 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: Defgeneric affects methods?
To: Common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: <871106-133128-1483@Xerox>
Message-ID: <19871106215202.4.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: 6 Nov 87 13:31 PST
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
RPG:
``Except it does affect existing methods if :method is
specified, so....''
Here is an issue brought up by wording problems: do you mean
that defgeneric affects the set of existing methods (such as
replacing some of them) or that defgeneric affects some individuals
because when one is ``replaced'' a method is destructively modified?
I think that this is an example where documentation indirection would
pay off. Describe what happens when one evaluates a defgeneric with no
:method options, and thee is an existing generic function. No existing
methods on the existing generic function is changed.
Then state that defgeneric with :method options is equivalent to a
defgeneric with no :method options follwoed by a set of defmethods. We
have said what happens there as well. Similar methods get replaced.
I agree with this approach. I think this is the same as what the document
already says, provided we remove the one offending remark.
∂06-Nov-87 1731 Common-Lisp-Object-System-mailer Re: format for description of generic functions in chapter 2
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 6 Nov 87 17:31:35 PST
Received: from Cabernet.ms by ArpaGateway.ms ; 06 NOV 87 17:25:27 PST
Date: 6 Nov 87 17:25 PST
From: Masinter.pa@Xerox.COM
Subject: Re: format for description of generic functions in chapter 2
In-reply-to: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>'s
message of Wed, 4 Nov 87 20:38 EST
To: Moon@STONY-BROOK.SCRC.Symbolics.COM
cc: common-lisp-object-system@SAIL.STANFORD.EDU
Message-ID: <871106-172527-1861@Xerox>
"To me lambda-list congruence seems equally applicable
to all generic functions and methods, and furthermore it's hard to see
how
generic functions could work or users could call them if there wasn't
lambda-list congruence. . . ."
There were numerous discussions of alternate rules for lambda-list
congruence than the ones that made it into the spec. Generic functions
could implicitly assume that they were defined with &rest, for example,
yet allow some methods to have &REST and others &KEY or even a set of
&OPTIONAL arguments. Allowing the number of arguments to vary by class
seems possible, too, although it might require a run-time test at method
entry to determine if the generic function handed on too many arguments
for that particular method.
∂09-Nov-87 1452 Common-Lisp-Object-System-mailer Current State of CLOS Draft
Received: from SCORE.STANFORD.EDU by SAIL.STANFORD.EDU with TCP; 9 Nov 87 14:52:20 PST
Received: from hplabs.HP.COM (hplabs.hpl.hp.com.#Internet) by SCORE.STANFORD.EDU with TCP; Mon 9 Nov 87 14:40:25-PST
Received: from hplms2 by hplabs.HP.COM with SMTP ; Mon, 9 Nov 87 14:45:00 PST
Received: from hplabsz.hpl.hp.com by hplms2; Mon, 9 Nov 87 14:44:45 pst
Return-Path: <kempf@hplabsz>
Received: from hplabsz by hplabsz; Mon, 9 Nov 87 15:44:19 pst
To: common-lisp-object-system@sail.stanford.edu
Subject: Current State of CLOS Draft
X-Mailer: mh6.5
Date: Mon, 09 Nov 87 15:44:12 MST
Message-Id: <2268.563496252@hplabsz>
From: kempf%hplabsz@hplabs.HP.COM
Is the current CLOS draft on sail in tex-able source form? If so, are
the files the usual ones, or different?
Also, has the location, agenda, and time for the meeting next Monday in
Fort Collins been set?
Thanks.
jak
∂10-Nov-87 1402 Common-Lisp-Object-System-mailer Agenda for X3J13
To: common-lisp-object-system@SAIL.Stanford.EDU
CC: mathis@C.ISI.EDU
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>
As you know, we ran into a brick wall last week with the specification.
The problem is with the question of how much the meta-object level
should influence the format and content of chapter 2. The issue is
how to decide what to say about the specification of a generic function
versus what to say about specific methods.
I think there is no question that this level of detail is worth
specifying, but the question was how much to try to do before the X3
meeting.
It turns out that the very question itself and our initial consideration
of it broke our stride enough that we will not be able to have
an extensive discussion at X3 because we will not have coherent
draft of chapters 1 and 2 in the hands of the X3 members soon enough.
Therefore, the following have been decided:
1. There will be no CLOS subcommittee meeting in Colorado.
2. Danny Bobrow, Sonya Keene, and Linda DeMichiel will not attend the meeting.
3. Gregor will present an overview of the decisions we made, such as
initialization, class redefinition, etc.
I'm sorry if this necessitates a change in your travel plans.
-rpg-
∂11-Nov-87 0757 Common-Lisp-Object-System-mailer Agenda for X3J13
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 11 Nov 87 07:57:29 PST
Received: from JUNCO.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 277003; Wed 11-Nov-87 10:28:24 EST
Date: Wed, 11 Nov 87 10:28 EST
From: Sonya E. Keene <skeene@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Agenda for X3J13
To: RPG@SAIL.Stanford.EDU
cc: common-lisp-object-system@SAIL.Stanford.EDU, mathis@C.ISI.EDU
In-Reply-To: The message of 10 Nov 87 17:02 EST from Dick Gabriel <RPG@SAIL.Stanford.EDU>
Message-ID: <19871111152820.2.SKEENE@JUNCO.SCRC.Symbolics.COM>
Date: 10 Nov 87 1402 PST
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>
As you know, we ran into a brick wall last week with the specification.
The problem is with the question of how much the meta-object level
should influence the format and content of chapter 2. The issue is
how to decide what to say about the specification of a generic function
versus what to say about specific methods.
I think there is no question that this level of detail is worth
specifying, but the question was how much to try to do before the X3
meeting.
It turns out that the very question itself and our initial consideration
of it broke our stride enough that we will not be able to have
an extensive discussion at X3 because we will not have coherent
draft of chapters 1 and 2 in the hands of the X3 members soon enough.
Therefore, the following have been decided:
1. There will be no CLOS subcommittee meeting in Colorado.
2. Danny Bobrow, Sonya Keene, and Linda DeMichiel will not attend the meeting.
I am going to the X3J13 meeting.
3. Gregor will present an overview of the decisions we made, such as
initialization, class redefinition, etc.
I'm sorry if this necessitates a change in your travel plans.
-rpg-
∂11-Nov-87 1441 Common-Lisp-Object-System-mailer making gf lambda lists
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 11 Nov 87 14:41:00 PST
Received: from Semillon.ms by ArpaGateway.ms ; 11 NOV 87 14:41:46 PST
Date: Wed, 11 Nov 87 14:41 PST
From: Gregor.pa@Xerox.COM
Subject: making gf lambda lists
To: common-lisp-object-system@sail.stanford.edu
Message-ID: <871111144109.3.GREGOR@SPIFF.isl.parc.xerox.com>
Line-fold: no
I believe that we are going to want to introduce a support function
called something like:
make-generic-function-lambda-list-from-specialized-method-lambda-list
This function will make it easier for programmers who are constructing
their own methods and generic functions to get themselves a congruent
generic function lambda list. This functions will strip out
specializers and optional defaults and remove uses of &key and &aux (and
anything else I might have forgotten).
Can anyone think of a better name for this function?
Can anyone think of a worse name?
-------
∂11-Nov-87 1451 Common-Lisp-Object-System-mailer scope of call-next-method
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 11 Nov 87 14:51:39 PST
Received: from Semillon.ms by ArpaGateway.ms ; 11 NOV 87 14:51:59 PST
Date: Wed, 11 Nov 87 14:51 PST
From: Gregor.pa@Xerox.COM
Subject: scope of call-next-method
To: common-lisp-object-system@sail.stanford.edu
Message-ID: <871111145127.4.GREGOR@SPIFF.isl.parc.xerox.com>
Line-fold: no
This message concerns the scope of call-next-method and next-method-p.
Recent drafts of the spec say that the scope of these functions include
the default value forms for optional and keyword arguments. I believe
that the scope of these should include only the body of the method.
I don't see how what the spec currently says can work. The problem is
that call-next-method is defined to have access to the bindings of the
arguments to the method. But if call-next-method is called during the
process of doing those bindings what arguments will it have access to?
What arguments will it pass to the next method? I believe the only
model that can work reasonably is that call next method is defined only
within the body of the method.
So, my model (and proposal) is that:
(defmethod foo ((x boat))
(body x))
expands to
.
.
(lambda (x)
(flet ((call-next-method (&rest args) ...)
(next-method-p () ...))
(body x)))
I realize that we could make the rules different for call-next-method
and next-method-p, but I think that would be gratuitous complexity and
incompatibility.
-------
∂11-Nov-87 1514 Common-Lisp-Object-System-mailer optimization in the spec
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 11 Nov 87 15:06:08 PST
Received: from Semillon.ms by ArpaGateway.ms ; 11 NOV 87 15:02:55 PST
Date: Wed, 11 Nov 87 15:02 PST
From: Gregor.pa@Xerox.COM
Subject: optimization in the spec
To: common-lisp-object-system@sail.stanford.edu
Message-ID: <871111150223.5.GREGOR@SPIFF.isl.parc.xerox.com>
Line-fold: no
In the latest draft of the spec, there are several places which
explicitly address legal optimizations an implementation might perform.
I find these somewhat confusing, and I think that instead we might want
to do the following:
1- Have an general, well worked out statement about what kinds of
optimization are legal in CLOS implementations. This statement
would be 'the optimization law'.
2- Have an appendix or implementation notes in the document reflecting
places in the design where the intent was to allow optimizations
that are in accordance with the 'the optimization law'.
As a start on this, here is a first crack on the law.
In order to insure program portability, there are strict rules which
must be followed when doing optimization of CLOS implementations. The
rules governing when error checking and signalling can be optimized away
have already been covered. Except where it is explicitly stated that
under certain compilation conditions it is permissible not to signal an
error, the rule governing optimizations is that no optimization can
change the behavior of a program. All optimizations must preserve the
semantics of the CLOS.
Examples of legal optimizations include:
Where the system can determine what methods will be called for a
particular invocation of a generic function, it might compile out the
method lookup.
Where methods have been declared inline (whatever that means) or are
system supplied methods, the system might compile calls (like the one
above) out entirely.
This is just rough, but I hope you can see what I am trying to capture.
That is that I am trying to make it clear that except where we say so
explicitly, a program can be sure that optimizations won't have weird
semantics. For example, the current text that talks about optimizing
initarg defaulting makes it sound like I could write a program which
could tell that some initarg defaulting had been optimized out. We need
to make it clear that no user program will be able to detect
optimization (except for the stuff about an error should be signalled).
-------
∂12-Nov-87 1330 Common-Lisp-Object-System-mailer scope of call-next-method
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 12 Nov 87 13:30:21 PST
Received: from Semillon.ms by ArpaGateway.ms ; 12 NOV 87 10:56:14 PST
Date: Thu, 12 Nov 87 10:55 PST
From: Gregor.pa@Xerox.COM
Subject: scope of call-next-method
To: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
cc: common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: <19871112172228.3.MOON@EUPHRATES.SCRC.Symbolics.COM>
Message-ID: <871112105535.3.GREGOR@SPIFF.isl.parc.xerox.com>
Line-fold: no
I would still rather have call-next-method only be valid in the body of
the method and let users who want to do defaulting using it do the
defaulting by hand in the obvious way. I believe that the model that
defmethod wrap an flet around their body is a great deal simpler than
the model required to explain the behavior you propose. Just compare:
(defmetod foo ((x class))
(body x))
call-next-method only available in body:
.
#'(lambda (x)
(flet ((call-next-method (&rest r) ..))
(body x)))
.
call-next-method available in body and default value forms:
.
#'(lambda (&rest #:c-n-m-arguments)
(flet ((call-next-method (&rest #:c-n-m-arguments)
(apply ... (or #:c-n-m-arguments #:arguments))))
(apply #'(lambda (x)
(body x))
#:c-n-m-arguments)))
.
-------
∂12-Nov-87 1411 Common-Lisp-Object-System-mailer scope of call-next-method
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 12 Nov 87 14:11:24 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 278010; Thu 12-Nov-87 12:22:49 EST
Date: Thu, 12 Nov 87 12:22 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: scope of call-next-method
To: Gregor.pa@Xerox.COM
cc: common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: <871111145127.4.GREGOR@SPIFF.isl.parc.xerox.com>
Message-ID: <19871112172228.3.MOON@EUPHRATES.SCRC.Symbolics.COM>
Line-fold: No
Date: Wed, 11 Nov 87 14:51 PST
From: Gregor.pa@Xerox.COM
This message concerns the scope of call-next-method and next-method-p.
Recent drafts of the spec say that the scope of these functions include
the default value forms for optional and keyword arguments. I believe
that the scope of these should include only the body of the method.
I don't see how what the spec currently says can work. The problem is
that call-next-method is defined to have access to the bindings of the
arguments to the method.
No. Call-next-method has access to the arguments. It explicitly does not
access the bindings of the parameters (-not- arguments) of the method.
But if call-next-method is called during the
process of doing those bindings what arguments will it have access to?
What arguments will it pass to the next method?
I think you've been misled by the arguments/parameters terminology.
Even though I'm pretty sure CLtL uses those terms consistently, and I
think the CLOS spec does as well, in informal talk people still often
get them mixed up, and the two words sound so similar that this is not
surprising, especially since other languages use other terminology.
Here's a simple example of a way to implement it, although I imagine
most implementations would find another way that is less simple but
more efficient in that particular implementation. Several obvious
improvements to the below will immediately spring to your mind.
For instance, it isn't necessary to use &rest.
(defmethod foo ((x boat) &optional (y (call-next-method)))
(body x y))
==>
(add-method ...
(make ...
#'(lambda (... &rest #:arguments)
(flet ((call-next-method (&rest #:c-n-m-arguments)
(apply ... (or #:c-n-m-arguments #:arguments)))
(next-method-p () ...))
(apply #'(lambda (x &optional (y (call-next-method)))
(body x y))
#:arguments)))))
∂12-Nov-87 1411 Common-Lisp-Object-System-mailer scope of call-next-method
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 12 Nov 87 14:11:43 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 278125; Thu 12-Nov-87 14:11:04 EST
Date: Thu, 12 Nov 87 14:10 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: scope of call-next-method
To: Gregor.pa@Xerox.COM
cc: common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: <871112105535.3.GREGOR@SPIFF.isl.parc.xerox.com>
Message-ID: <19871112191046.2.MOON@EUPHRATES.SCRC.Symbolics.COM>
Line-fold: No
Date: Thu, 12 Nov 87 10:55 PST
From: Gregor.pa@Xerox.COM
I would still rather have call-next-method only be valid in the body of
the method and let users who want to do defaulting using it do the
defaulting by hand in the obvious way. I believe that the model that
defmethod wrap an flet around their body is a great deal simpler than
the model required to explain the behavior you propose.
I believe precisely the opposite, particularly since the way this is
explained to users surely does not involve writing out lambda
expressions and flets. That's only a way to explain it to implementors.
I think you're concentrating too much on the implementation and not
enough on the semantics. I propose that we leave call-next-method the
way it is and not change it.
I believe it's simpler to say that call-next-method works anywhere in a
method than to say it only works some places in a method, thus having to
say that if you use it in argument defaulting, you have to do the
argument defaulting a different way than you would ordinarily do it.
By the way, I tried the scoping you propose in Flavors, for the same
reason I think: I was concentrating too much on the implementation and
not enough on the semantics. My users forced me to change it to the
scoping I propose. These were outside users, not Symbolics people.
∂12-Nov-87 1821 Common-Lisp-Object-System-mailer Re: optimization in the spec
Received: from SCORE.STANFORD.EDU by SAIL.STANFORD.EDU with TCP; 12 Nov 87 18:20:43 PST
Received: from hplabs.HP.COM (hplabs.hpl.hp.com.#Internet) by SCORE.STANFORD.EDU with TCP; Thu 12 Nov 87 17:36:47-PST
Received: from hplms2.HP.COM (hplms2) by hplabs.HP.COM with SMTP ; Thu, 12 Nov 87 14:38:47 PST
Received: from hplabsz.hpl.hp.com by hplms2.HP.COM; Thu, 12 Nov 87 14:38:25 pst
Return-Path: <kempf@hplabsz>
Received: from hplabsz by hplabsz; Thu, 12 Nov 87 15:38:00 pst
To: Gregor.pa@Xerox.COM
Cc: common-lisp-object-system@sail.stanford.edu
Subject: Re: optimization in the spec
X-Mailer: mh6.5
In-Reply-To: Your message of Wed, 11 Nov 87 15:02:00 -0800.
<871111150223.5.GREGOR@SPIFF.isl.parc.xerox.com>
Date: Thu, 12 Nov 87 15:37:57 MST
Message-Id: <27762.563755077@hplabsz>
From: kempf%hplabsz@hplabs.HP.COM
> 1- Have an general, well worked out statement about what kinds of
> optimization are legal in CLOS implementations. This statement
> would be 'the optimization law'.
I think the general statement should be that no implementation should
perform an optimization which could cause a change in CLOS semantics.
This statement might, in fact, be TOO general, since it might rule
out things like in-lining slot access, which would cause the class
changing protocol to break. But in-lining slot access is a natural
optimization to want to do after code has been developed and the
class definition stabilizes, when the class changing protocol doesn't
matter any more. . So maybe the statement needs to be tied to the safety level.
> 2- Have an appendix or implementation notes in the document reflecting
> places in the design where the intent was to allow optimizations
> that are in accordance with the 'the optimization law'.
This is a good idea. The hints on optimization scattered about the
document should probably be gathered into an implementation notes
appendix, or (less preferable) set off from the text as in CLtL.
∂13-Nov-87 0833 Common-Lisp-Object-System-mailer Scope of Call-next-method
Received: from RELAY.CS.NET by SAIL.STANFORD.EDU with TCP; 13 Nov 87 08:33:36 PST
Received: from relay2.cs.net by RELAY.CS.NET id aa07028; 13 Nov 87 11:18 EST
Received: from csl.ti.com by RELAY.CS.NET id aa12107; 13 Nov 87 11:18 EST
Received: from Jenner by tilde id AA24782; Fri, 13 Nov 87 09:01:33 CST
Message-Id: <2772802735-10721025@Jenner>
Date: Fri, 13 Nov 87 08:58:55 CST
From: Patrick H Dussud <DUSSUD%jenner.csc.ti.com@RELAY.CS.NET>
To: common-lisp-object-system@SAIL.STANFORD.EDU
Subject: Scope of Call-next-method
In-Reply-To: Msg of Thu, 12 Nov 87 14:10 EST from "David A. Moon" <Moon@scrc-stony-brook.arpa>
I believe it's simpler to say that call-next-method works anywhere in a
method than to say it only works some places in a method, thus having to
say that if you use it in argument defaulting, you have to do the
argument defaulting a different way than you would ordinarily do it.
Of course it is simpler to say that call-next-method works anywhere in a
method. An example will be make clear the fact that CALL-NEXT-METHOD
without arguments uses the method arguments, not its parameters.
Patrick.
∂13-Nov-87 1119 Common-Lisp-Object-System-mailer optimization in the spec
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 13 Nov 87 11:19:11 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 279096; Fri 13-Nov-87 14:19:05 EST
Date: Fri, 13 Nov 87 14:18 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: optimization in the spec
To: common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: <871111150223.5.GREGOR@SPIFF.isl.parc.xerox.com>
Message-ID: <19871113191855.2.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Wed, 11 Nov 87 15:02 PST
From: Gregor.pa@Xerox.COM
In the latest draft of the spec, there are several places which
explicitly address legal optimizations an implementation might perform.
I find these somewhat confusing, and I think that instead we might want
to do the following:
1- Have an general, well worked out statement about what kinds of
optimization are legal in CLOS implementations. This statement
would be 'the optimization law'.
2- Have an appendix or implementation notes in the document reflecting
places in the design where the intent was to allow optimizations
that are in accordance with the 'the optimization law'.
I think organizing it this way would be a good idea, although it could
involve a lot of work for a relatively small benefit. Also, in some cases,
such as object creation, it needs to be noted directly in the document that
the semantics have been relaxed to allow for increased optimization. This
was a very deliberate decision by the group, as I recall.
I don't have a good feel for whether it's better to describe these things
in terms of "optimization", as we do now, or simply to say that it is
implementation-dependent. The former way has the advantage of motivating
the reason for not requiring a particular behavior, while the latter is
more like CLtL.
As a start on this, here is a first crack on the law.
In order to insure program portability, there are strict rules which
must be followed when doing optimization of CLOS implementations. The
rules governing when error checking and signalling can be optimized away
have already been covered. Except where it is explicitly stated that
under certain compilation conditions it is permissible not to signal an
error, the rule governing optimizations is that no optimization can
change the behavior of a program. All optimizations must preserve the
semantics of the CLOS.
This is just a motherhood statement and begs the question "what, precisely,
are the semantics of CLOS."
We need
to make it clear that no user program will be able to detect
optimization (except for the stuff about an error should be signalled).
Of course user programs will be able to detect optimization, because we are
giving access to implementation-dependent details, for instance through the
meta-object protocol. Your statement is almost as strong as "it is impossible
to write a Common Lisp program that is not portable." I think what you really
mean is that CLOS defines a certain semantics that portable programs can
depend on, and optimizations, like everything else, must conform to that
semantics. That portable semantics does not fully specify every detail of
CLOS execution.
∂14-Nov-87 1453 Common-Lisp-mailer questions about CLOS [original subject: equality of structures]
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 14 Nov 87 14:52:54 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 279905; Sat 14-Nov-87 17:52:14 EST
Date: Sat, 14 Nov 87 17:52 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: questions about CLOS [original subject: equality of structures]
To: goldman@vaxa.isi.edu
cc: COMMON-LISP@SAIL.STANFORD.EDU, Common-Lisp-Object-System@SAIL.STANFORD.EDU
In-Reply-To: <8711092000.AA14975@vaxa.isi.edu>
Message-ID: <19871114225202.0.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Mon, 09 Nov 87 12:00:35 PST
From: goldman@vaxa.isi.edu
Re: the suggestion that CLOS should subsume (by convention or otherwise)
uses of un:TYPEed defstruct types?
I presume that this takes care of the issue of EQUAL, because the CLOS
specifies the semantics of EQUAL for its class instances? (What is the
specification, by the way?)
CLOS does not currently say anything about how the functions EQUAL, EQUALP,
and EQL behave on instances of standard classes (you can read the last four
words as equivalent to "user-defined objects"). It also doesn't say
anything about the type-specific equality functions CHAR-EQUAL,
CHAR-NOT-EQUAL, TREE-EQUAL, STRING-EQUAL, and STRING-NOT-EQUAL, nor
the 6 type-specific = and /= functions.
It would fit the structure of CLOS to say that EQUAL and EQUALP will be
expanded to generic functions whose behavior can be extended by defining
methods. I don't think we would want to allow extending EQL or the
type-specific functions, since CLOS does not claim to be so powerful as
to allow you to create new types of numbers, characters, or strings.
Extending EQ would not make any sense, of course.
I suspect the reason CLOS currently shys away from EQUAL and EQUALP is
that the equality predicates in Common Lisp are clearly not very well
chosen and beg for a lot of cleaning up based on a better theory of what
we want. To give just one example, it's peculiar that comparing arrays
element-by-element has been bundled together with ignoring alphabetic case.
It's probably better to wait for Common Lisp to get its act together
before extending CLOS into this area; clearly, equality methods can be
added later to the standard or to an individual implementation without
any incompatibilities, so there's no rush.
A possible additional reason is that CLOS does not deal terribly well
with symmetric two-argument functions such as EQUAL. It's possible to
specialize them, but you usually have to define a lot of seemingly
extraneous methods, since the generic function dispatch mechanism has
no concept of commutativity nor of type translation.
But I would be loathe to replace my un:TYPEed
defstructs with DEFCLASSes if I gave up substantial efficiency when I only
wanted the limited power provided by the "record structure" semantics.
Are there enough declarations available in CLOS so that I could get
my compiled accesses to slots of such instances down to the equivalent
of an array element reference?
As an implementation-independent language specification, CLOS does not
and cannot directly address this issue. However, it's clear what would
generally need to be declared to allow implementations to do something
like that, although you would have to look at each individual implementation
to see whether it was faster or slower than arrays with declarations;
you might even find an implementation where slot access was faster than
array access even without declarations. Basically what you need to declare
is that the class cannot be redefined or subclassed. Some members of the
CLOS subcommittee volunteered to propose declaration names and syntaxes
to allow for this type of optimization, but they haven't finished yet.
However, it is intended that most CLOS implementations either be very
efficient or have a way to make them very efficient through declarations.
∂19-Nov-87 1714 Common-Lisp-Object-System-mailer symbol-macrolet
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 19 Nov 87 17:13:56 PST
Received: from Semillon.ms by ArpaGateway.ms ; 19 NOV 87 17:13:45 PST
Date: Thu, 19 Nov 87 17:13 PST
From: Gregor.pa@Xerox.COM
Subject: symbol-macrolet
To: common-lisp-object-system@sail.stanford.edu
Message-ID: <871119171306.3.GREGOR@SPIFF.isl.parc.xerox.com>
Line-fold: no
I suppose we should say explicitly that the symbol macros are recorded
in the macroexpansion environment so that macroexpand-1 of a symbol
which is a symbol-macro will expand it.
In the text in my draft, this would correspond to including something
like the following in remarks.
Within the body of symbol-macrolet the macroexpansion environment is
augmented to include a symbol-macro definition for the symbol. When
given the symbol and the environment as arguments, macroexpand-1 will
return the expansion. This means that a macro which appears in the
scope of symbol-macrolet can use macroexpand-1 to determine whether or
not a symbol names a symbol macro; this is particularly useful for
macros which want to determine whether or not their argument is a
symbol.
Examples:
(defmacro ↑2 (form &optional environment)
(if (and (symbolp form)
(eq (macroexpand-1 form) environment))
`(* ,form ,form)
`(expt ,form 2)))
This is a pretty lame example. Hopefully we can come up with something
else that is as simple but more compelling.
Also, we may want to mention explicitly the zetalisp macro once-only.
-------
∂20-Nov-87 0343 Common-Lisp-Object-System-mailer Re: symbol-macrolet
Received: from [128.89.1.216] by SAIL.STANFORD.EDU with TCP; 20 Nov 87 03:43:30 PST
To: Gregor.pa@XEROX.COM
cc: common-lisp-object-system@SAIL.STANFORD.EDU
Subject: Re: symbol-macrolet
In-reply-to: Your message of Thu, 19 Nov 87 17:13:00 -0800.
<871119171306.3.GREGOR@SPIFF.isl.parc.xerox.com>
Date: Fri, 20 Nov 87 06:37:20 -0500
From: kanderso@WILMA.BBN.COM
I think there was an obvious bug in your example. How about:
(defmacro ↑2 (form &optional environment)
(if (and (symbolp form)
(eq (macroexpand-1 form environment) form) ; <-
`(* ,form ,form)
`(expt ,form 2)))
I tried to come up with another example. This is more generic
(dispatching on whether the form is a symbol or not) but it seems
more lame.
(defun dispatch (form &optional environment)
(if (symbolp form)
(setq form (macroexpand-1 form environment)))
(if (and (symbolp form)
(special-symbol form))
(dispatch-special-symbol form environment)
(dispatch-form form envrionment)))
k
∂20-Nov-87 0944 Common-Lisp-Object-System-mailer Re: symbol-macrolet
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 20 Nov 87 09:44:27 PST
Received: from Semillon.ms by ArpaGateway.ms ; 20 NOV 87 09:44:09 PST
Date: Fri, 20 Nov 87 09:43 PST
From: Gregor.pa@Xerox.COM
Subject: Re: symbol-macrolet
To: kanderso@WILMA.BBN.COM
cc: common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: The message of 20 Nov 87 03:37 PST from
kanderso@WILMA.BBN.COM
Message-ID: <871120094332.9.GREGOR@SPIFF.parc.xerox.com>
Line-fold: no
Date: Fri, 20 Nov 87 06:37:20 -0500
From: kanderso@WILMA.BBN.COM
I think there was an obvious bug in your example. How about:
(defmacro ↑2 (form &optional environment)
(if (and (symbolp form)
(eq (macroexpand-1 form environment) form) ; <-
`(* ,form ,form)
`(expt ,form 2)))
Oops, you're right. I forgot NOT. Instead it should be:
(defmacro ↑2 (form &optional environment)
(if (and (symbolp form)
(not (eq (macroexpand-1 form environment) form)))
`(* ,form ,form)
`(expt ,form 2)))
-------
∂20-Nov-87 1455 Common-Lisp-Object-System-mailer Re: symbol-macrolet
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 20 Nov 87 14:55:13 PST
Received: from Semillon.ms by ArpaGateway.ms ; 20 NOV 87 14:54:54 PST
Date: Fri, 20 Nov 87 14:54 PST
From: Gregor.pa@Xerox.COM
Subject: Re: symbol-macrolet
To: common-lisp-object-system@SAIL.STANFORD.EDU
cc: kanderso@WILMA.BBN.COM
In-Reply-To: <871120094332.9.GREGOR@SPIFF.parc.xerox.com>
Message-ID: <871120145418.2.GREGOR@SPIFF.parc.xerox.com>
Line-fold: no
OK, lets try this again. Maybe I will get it right this time:
I am not supposed to have the NOT, and environment is an &environment
argument not an &optional argument. Also today is Friday, its daylight,
and my name is Gregor. I think I have it now.
(defmacro ↑2 (form &environment environment)
(if (and (symbolp form)
(eq (macroexpand-1 form environment) form))
`(* ,form ,form)
`(expt ,form 2)))
-------
∂23-Nov-87 1041 Common-Lisp-Object-System-mailer Re: symbol-macrolet
Received: from RELAY.CS.NET by SAIL.STANFORD.EDU with TCP; 23 Nov 87 10:41:08 PST
Received: from relay2.cs.net by RELAY.CS.NET id ae10335; 23 Nov 87 13:31 EST
Received: from csl.ti.com by RELAY.CS.NET id au19978; 23 Nov 87 13:24 EST
Received: from Jenner by tilde id AA17820; Mon, 23 Nov 87 11:21:58 CST
Message-Id: <2773675077-8251807@Jenner>
Date: Mon, 23 Nov 87 11:17:57 CST
From: Patrick H Dussud <DUSSUD%jenner.csc.ti.com@RELAY.CS.NET>
To: Gregor.pa@XEROX.COM
Cc: common-lisp-object-system@SAIL.STANFORD.EDU
Subject: Re: symbol-macrolet
In-Reply-To: Msg of Fri, 20 Nov 87 14:54 PST from Gregor.pa@xerox.com
I suppose we should say explicitly that the symbol macros are recorded
in the macroexpansion environment so that macroexpand-1 of a symbol
which is a symbol-macro will expand it.
In the text in my draft, this would correspond to including something
like the following in remarks.
Within the body of symbol-macrolet the macroexpansion environment is
augmented to include a symbol-macro definition for the symbol. When
given the symbol and the environment as arguments, macroexpand-1 will
return the expansion. This means that a macro which appears in the
scope of symbol-macrolet can use macroexpand-1 to determine whether or
not a symbol names a symbol macro; this is particularly useful for
macros which want to determine whether or not their argument is a
symbol.
It sounds good.
Patrick.
∂23-Nov-87 1220 Common-Lisp-Object-System-mailer symbol-macrolet
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 23 Nov 87 12:20:26 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 286861; Mon 23-Nov-87 15:19:41 EST
Date: Mon, 23 Nov 87 15:19 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: symbol-macrolet
To: Gregor.pa@Xerox.COM
cc: common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: <871119171306.3.GREGOR@SPIFF.isl.parc.xerox.com>,
The message of 20 Nov 87 06:37 EST from kanderso@WILMA.BBN.COM,
<871120094332.9.GREGOR@SPIFF.parc.xerox.com>,
<871120145418.2.GREGOR@SPIFF.parc.xerox.com>,
<2773675077-8251807@Jenner>
Message-ID: <19871123201936.6.MOON@EUPHRATES.SCRC.Symbolics.COM>
Line-fold: No
Date: Thu, 19 Nov 87 17:13 PST
From: Gregor.pa@Xerox.COM
I suppose we should say explicitly that the symbol macros are recorded
in the macroexpansion environment so that macroexpand-1 of a symbol
which is a symbol-macro will expand it.
I thought we were going to allow SYMBOL-MACROLET to be implemented in a
portable way, as something that fully macroexpands the form given and
then makes substitutions for symbols in it. During macroexpansion the
symbol-macrolet'ed symbols would be just like other symbols, which seems
okay since they are (I think) supposed to be used in ways that are
semantically like variables; certainly that's true in the case of
WITH-SLOTS.
You seem to be suggesting that instead we will require every
implementation to change its macro mechanism to support symbol macros
directly. Does this also require that every implementation must change
its interpreter and compiler to macroexpand symbols as well as lists
before attempting to evaluate them? Whether the answer to that is yes or
no, it seems likely that every implementation would have to change its
internal representation of lexical environments, to allow for symbols to
be "bound" to macros as well as to values. We might get a great deal of
resistance to that from some implementations.
Unless we can come up with some more compelling examples than so far, I
don't think CLOS should require SYMBOL-MACROLET to do anything to the
macroexpansion environment. I think we should stick with the very
simple and easy to understand definition of SYMBOL-MACROLET that we have
now: "Each reference to -symbol- as a variable within the lexical scope
of symbol-macrolet is replaced by -expansion-." Both examples so far
appear to be predicated on the assumption that a call to SLOT-VALUE is
much less efficient than accessing a variable, and therefore we want to
allow for common subexpression optimization to be done by hand for these
in a funny way. I for one see no reason to stipulate that inefficiency,
nor to assume that CSE optimizations must be done by hand.
∂23-Nov-87 1306 Common-Lisp-Object-System-mailer symbol-macrolet
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 23 Nov 87 13:06:30 PST
Received: from Semillon.ms by ArpaGateway.ms ; 23 NOV 87 13:05:11 PST
Date: Mon, 23 Nov 87 13:04 PST
From: Gregor.pa@Xerox.COM
Subject: symbol-macrolet
To: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
cc: common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: <19871123201936.6.MOON@EUPHRATES.SCRC.Symbolics.COM>
Message-ID: <871123130424.8.GREGOR@SPIFF.parc.xerox.com>
Line-fold: no
Date: Mon, 23 Nov 87 15:19 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Date: Thu, 19 Nov 87 17:13 PST
From: Gregor.pa@Xerox.COM
I suppose we should say explicitly that the symbol macros are recorded
in the macroexpansion environment so that macroexpand-1 of a symbol
which is a symbol-macro will expand it.
I thought we were going to allow SYMBOL-MACROLET to be implemented in a
portable way, as something that fully macroexpands the form given and
then makes substitutions for symbols in it. During macroexpansion the
symbol-macrolet'ed symbols would be just like other symbols, which seems
okay since they are (I think) supposed to be used in ways that are
semantically like variables; certainly that's true in the case of
WITH-SLOTS.
You seem to be suggesting that instead we will require every
implementation to change its macro mechanism to support symbol macros
directly. Does this also require that every implementation must change
its interpreter and compiler to macroexpand symbols as well as lists
before attempting to evaluate them? Whether the answer to that is yes or
no, it seems likely that every implementation would have to change its
internal representation of lexical environments, to allow for symbols to
be "bound" to macros as well as to values. We might get a great deal of
resistance to that from some implementations.
Unless we can come up with some more compelling examples than so far, I
don't think CLOS should require SYMBOL-MACROLET to do anything to the
macroexpansion environment. I think we should stick with the very
simple and easy to understand definition of SYMBOL-MACROLET that we have
now: "Each reference to -symbol- as a variable within the lexical scope
of symbol-macrolet is replaced by -expansion-." Both examples so far
appear to be predicated on the assumption that a call to SLOT-VALUE is
much less efficient than accessing a variable, and therefore we want to
allow for common subexpression optimization to be done by hand for these
in a funny way. I for one see no reason to stipulate that inefficiency,
nor to assume that CSE optimizations must be done by hand.
Well, my concern was that there were macros which use once-only for
semanic reasons rather than purely optimization reasons. These macros
assume that if a variable is lexical, they can know whether that
variable is being modified in their scope, they can perform some
optimizations. Granted, this is bad macro writing style, but I claim
that it is common. Its also true that the cases where these macros will
break is rare, but they do exist, and it makes me uncomfortable to think
there will be no way of fixing them.
On the other hand, I agree that it makes me unhappy to have to modify
the behavior of macroexpand-1 this way, and to modify the behavior of
the interpreter this way. I had not realized that this was such a
radical change.
I guess now I am not sure. Maybe the best thing to do is leave
symbol-macrolet the way you suggested and just document the exact form
of lossage I am describing.
Let me take this space to present one view of how macroexpansion
environments could be made more useful. If they were themselves a
function, which could be given an operation and arguments, and if the
default function accepted operations to macroexpand-1, fboundp, etc.
then I could just extend these things by wrapping my own function around
them which carried additional information. That would make it possible
to write a portable code walker in Common Lisp. But it would not solve
this problem.
-------
∂23-Nov-87 1758 Common-Lisp-Object-System-mailer making gf lambda lists
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 23 Nov 87 17:57:54 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 287364; Mon 23-Nov-87 20:57:15 EST
Date: Mon, 23 Nov 87 20:57 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: making gf lambda lists
To: Gregor.pa@Xerox.COM
cc: common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: <871111144109.3.GREGOR@SPIFF.isl.parc.xerox.com>
Message-ID: <19871124015712.1.MOON@EUPHRATES.SCRC.Symbolics.COM>
Line-fold: No
Date: Wed, 11 Nov 87 14:41 PST
From: Gregor.pa@Xerox.COM
I believe that we are going to want to introduce a support function
called something like:
make-generic-function-lambda-list-from-specialized-method-lambda-list
This function will make it easier for programmers who are constructing
their own methods and generic functions to get themselves a congruent
generic function lambda list. This functions will strip out
specializers and optional defaults and remove uses of &key and &aux (and
anything else I might have forgotten).
Can anyone think of a better name for this function?
No name.
I have too much mail backlog to find it now, but I think I suggested
that the making of a generic function should accept any form of lambda
list and should strip it itself. Maybe I only suggested that for
methods, but I think it should apply to both methods and generic
functions that you can hand in anything that can be coerced into the
right thing. "Hand in" means as a :lambda-list argument to
ensure-generic-function or to make-instance of the appropriate class.
It's always a metter of philosophy whether to bring functions like
this that we know are in there someplace out into the open and give
them documented names. I like the SETF approach, which says to
document only the ones that the user really has to know about.
∂24-Nov-87 1144 Common-Lisp-Object-System-mailer Re: making gf lambda lists
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 24 Nov 87 11:44:03 PST
Received: from Semillon.ms by ArpaGateway.ms ; 24 NOV 87 11:39:14 PST
Date: Tue, 24 Nov 87 11:36:03 PST
From: Ken Kahn <Kahn.pa@Xerox.COM>
Subject: Re: making gf lambda lists
In-Reply-To: <19871124015712.1.MOON@EUPHRATES.SCRC.Symbolics.COM>
To: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
cc: Gregor.pa@Xerox.COM, common-lisp-object-system@SAIL.STANFORD.EDU
Message-ID: <871124-113914-4047@Xerox>
> It's always a metter of philosophy whether to bring functions like
this
> that we know are in there someplace out into the open and give them
documented
> names. I like the SETF approach, which says to document only the
ones
> that the user really has to know about.
I agree with the philosophy but find it curious that the proposal to
have SETF named functions is to remedy the fact that the SETF macro
approach hides things which people discovered they sometimes need.
References
Moon@STONY-BROOK.SCRC.Symbolics.COM's message of Mon, 23 Nov 87
20:57:00 EST -- making gf lambda lists
∂30-Nov-87 1049 Common-Lisp-Object-System-mailer :accessor slot option
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 30 Nov 87 10:48:59 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via INTERNET with SMTP id 290722; 30 Nov 87 13:48:49 EST
Date: Mon, 30 Nov 87 13:48 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: :accessor slot option
To: Common-Lisp-Object-System@SAIL.STANFORD.EDU
In-Reply-To: <871102133014.0.GREGOR@SPIFF.isl.parc.xerox.com>
Message-ID: <19871130184852.9.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Mon, 2 Nov 87 13:30 PST
From: Gregor.pa@Xerox.COM
I have become uncomfortable with the :reader and :accessor slot options.
Right now, at the very least, I would like to add a :writer option, I
may also want to remove or rename the :accessor option. The :writer
option would work in the obvious way:
(defclass foo ()
((a :reader foo-a
:writer (setf foo-a))))
This would allow someone who wanted to define a writer but no reader to
do it, it also makes the mapping onto the new setf proposal more
explicit.
I agree that adding a :writer slot-option is a good idea. This would
make some of my users happier. This makes the CLOS specification slightly
larger, but it's probably worth it. It certainly doesn't make CLOS more
-conceptually- complex.
I agree that in cases where you want both a reader and a writer its
probably too verbose, so we probably need to keep the :accessor option,
but what if we renamed it, maybe to :reader-writer or perhaps
:accessors.
The name :accessors is definitely out; mixed singular and plural option
names always lead to trouble. I don't think :accessor is too bad a name
to imply a function that works for both reading and writing. If I was
teaching CLOS to someone, I think I would teach them :accessor first,
as the one that you usually use, and then later say "actually :accessor
can be broken down into its two component parts, :reader and :writer,
in case you have your special reasons to want to get at them separately."
What about the plural option name :default-initargs? I think this is
the only plural option we have, except for :qualifiers and :specializers
arguments when making a method, and those are legitimately plural to
show that their values are lists.
The name :default-initargs can be justified on the basis that it can
default more than one "initarg", but it might be worth rethinking this
name to avoid plurality and to avoid the jargon word "initarg," which
has been demoted to a less prominent place in the CLOS specification
than it had originally. :default-initialization was the best name I
could come up with, maybe someone else can do better.
∂01-Dec-87 2103 Common-Lisp-Object-System-mailer Re: symbol-macrolet
Received: from SCORE.STANFORD.EDU by SAIL.STANFORD.EDU with TCP; 1 Dec 87 21:03:07 PST
Received: from hplabs.HP.COM by SCORE.STANFORD.EDU with TCP; Tue 1 Dec 87 20:57:39-PST
Received: from hplms2.HP.COM (hplms2) by hplabs.HP.COM with SMTP ; Mon, 30 Nov 87 16:04:43 PST
Received: from hplabsz.hpl.hp.com by hplms2.HP.COM; Mon, 30 Nov 87 16:04:14 pst
Return-Path: <kempf@hplabsz>
Received: from hplabsz by hplabsz; Mon, 30 Nov 87 17:03:51 pst
To: "David A. Moon" <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Cc: Gregor.pa@Xerox.COM, common-lisp-object-system@SAIL.STANFORD.EDU
Subject: Re: symbol-macrolet
X-Mailer: mh6.5
In-Reply-To: Your message of Mon, 23 Nov 87 15:19:00 -0500.
<19871123201936.6.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Mon, 30 Nov 87 17:03:48 MST
Message-Id: <5270.565315428@hplabsz>
From: kempf%hplabsz@hplabs.HP.COM
> Date: Thu, 19 Nov 87 17:13 PST
> From: Gregor.pa@Xerox.COM
> I suppose we should say explicitly that the symbol macros are recorded
> in the macroexpansion environment so that macroexpand-1 of a symbol
> which is a symbol-macro will expand it.
> I thought we were going to allow SYMBOL-MACROLET to be implemented in a
> portable way, as something that fully macroexpands the form given and
> then makes substitutions for symbols in it. During macroexpansion the
> symbol-macrolet'ed symbols would be just like other symbols, which seems
> okay since they are (I think) supposed to be used in ways that are
> semantically like variables; certainly that's true in the case of
> WITH-SLOTS.
This is, in fact, how LET-PSEUDO (our version of SYMBOL-MACROLET) works.
First, all macros are expanded, and then the symbols are macroleted. User
defined macros thus treat the symbols like regular symbols, which is what,
I think, you want when considering them as variables, as you mentioned.
The macroexpansion environment is left untouched.
jak
∂01-Dec-87 2113 Common-Lisp-Object-System-mailer Re: :accessor slot option
Received: from SCORE.STANFORD.EDU by SAIL.STANFORD.EDU with TCP; 1 Dec 87 21:13:21 PST
Received: from hplabs.HP.COM by SCORE.STANFORD.EDU with TCP; Tue 1 Dec 87 21:07:54-PST
Received: from hplms2.HP.COM (hplms2) by hplabs.HP.COM with SMTP ; Mon, 30 Nov 87 14:48:17 PST
Received: from hplabsz.hpl.hp.com by hplms2.HP.COM; Mon, 30 Nov 87 14:47:44 pst
Return-Path: <kempf@hplabsz>
Received: from hplabsz by hplabsz; Mon, 30 Nov 87 15:47:20 pst
To: "David A. Moon" <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Cc: Common-Lisp-Object-System@SAIL.STANFORD.EDU
Subject: Re: :accessor slot option
X-Mailer: mh6.5
In-Reply-To: Your message of Mon, 30 Nov 87 13:48:00 -0500.
<19871130184852.9.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Mon, 30 Nov 87 15:47:17 MST
Message-Id: <4168.565310837@hplabsz>
From: kempf%hplabsz@hplabs.HP.COM
> I agree that adding a :writer slot-option is a good idea. This would
> make some of my users happier. This makes the CLOS specification slightly
> larger, but it's probably worth it. It certainly doesn't make CLOS more
> -conceptually- complex.
> I agree that in cases where you want both a reader and a writer its
> probably too verbose, so we probably need to keep the :accessor option,
> but what if we renamed it, maybe to :reader-writer or perhaps
> :accessors.
> The name :accessors is definitely out; mixed singular and plural option
> names always lead to trouble. I don't think :accessor is too bad a name
> to imply a function that works for both reading and w> r> iting. If I was
> teaching CLOS to someone, I think I would teach them :accessor first,
> as the one that you usually use, and then later say "actually :accessor
> can be broken down into its two component parts, :reader and :writer,
> in case you have your special reasons to want to get at them separately."
For what it's worth, I prefer just having a :reader and :writer option, and
if people want both they can specify both. Sort of like file protections
on some OS's.
> The name :default-initargs can be justified on the basis that it can
> default more than one "initarg", but it might be worth rethinking this
> name to avoid plurality and to avoid the jargon word "initarg," which
> has been demoted to a less prominent place in the CLOS specification
> than it had originally. :default-initialization was the best name I
> could come up with, maybe someone else can do better.
Yes.
jak
∂03-Dec-87 1914 Common-Lisp-Object-System-mailer mop
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 3 Dec 87 19:14:09 PST
Received: from Semillon.ms by ArpaGateway.ms ; 03 DEC 87 19:12:41 PST
Date: Thu, 3 Dec 87 19:11 PST
From: Gregor.pa@Xerox.COM
Subject: mop
To: common-lisp-object-system@sail.stanford.edu
Fcc: BD:>Gregor>mail>outgoing-mail-1.text
Message-ID: <871203191130.8.GREGOR@SPIFF.parc.xerox.com>
Line-fold: no
It may help in your reading now to know that the sections Danny and I
are working on now are class updating and method lookup. There were a
number of problems in both those sections. We hope to have a new
version on Sail tomorrow afternoon with rewritten versions of those
sections.
-------
∂04-Dec-87 1754 Common-Lisp-Object-System-mailer the mop
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 4 Dec 87 17:54:51 PST
Received: from Semillon.ms by ArpaGateway.ms ; 04 DEC 87 17:33:31 PST
Date: Fri, 4 Dec 87 17:06 PST
From: Gregor.pa@Xerox.COM
Subject: the mop
To: common-lisp-object-system@sail.stanford.edu
Message-ID: <871204170622.0.GREGOR@SPIFF.parc.xerox.com>
Line-fold: no
There is a slightly improved version of the mop on sail in the usual
place. As usual any comments appreciated.
-------
∂07-Dec-87 0944 RPG MOP comments part 1.
∂04-Dec-87 1641 @RELAY.CS.NET:DUSSUD@jenner.csc.ti.com MOP comments part 1.
Received: from RELAY.CS.NET by SAIL.STANFORD.EDU with TCP; 4 Dec 87 16:37:52 PST
Received: from relay2.cs.net by RELAY.CS.NET id aa08958; 4 Dec 87 19:11 EST
Received: from csc.ti.com by RELAY.CS.NET id ah11917; 4 Dec 87 18:57 EST
Received: from Jenner by tilde id AA22416; Fri, 4 Dec 87 17:27:32 CST
Message-Id: <2774647634-6446503@Jenner>
Date: Fri, 4 Dec 87 17:27:14 CST
From: Patrick H Dussud <DUSSUD%jenner.csc.ti.com@RELAY.CS.NET>
To: Gregor.pa@XEROX.COM
Cc: Moon@SCRC-STONY-BROOK.ARPA, SKeene@SCRC-STONY-BROOK.ARPA,
RPG@SAIL.STANFORD.EDU, LGD@SAIL.STANFORD.EDU,
DUSSUD%jenner.csc.ti.com@RELAY.CS.NET, kempf%hplabsz@hplabs.hp.com,
Bobrow.PA@XEROX.COM
Subject: MOP comments part 1.
In-Reply-To: Msg of Tue, 1 Dec 87 14:40 PST from Gregor.pa@xerox.com
I like this draft much better than the first draft that came out last march.
- Section: Class Organization in the CLOS Kernel
I find the argumentation in favor of common base design not very convincing.
Secondly, once
one has understood the features of standard-class one has a complete
view of the underlying implementation.
This is a feature of the protocol, not the class organization. This is so
because someone can and will turn off or override some features that are taken
for granted on standard classes. For each generic function, we must describe
what is an intangible behavior and what is left to interpretation by
implementing method.
Having the mixins is fine if you have cut
the world exactly right for the variation of class behavior one wants.
However, if not, then one has the same type of problem with overriding
unwanted behavior with multiple mixins
I agree with this. If we think that we can't get it right in a reasonnable
amount of time, then I want to suggest an alternative:
(defclass basic-class ())
(defclass standard-allocation-class (basic-class))
(defclass structure-allocation-class (basic-class))
(defclass standard-class (standard-allocation-class) ...)
(defclass structure-class (structure-allocation-class) ...)
(defclass built-in-class (basic-class))
That's a minimal approach that preserves modularity (no turning off/on methods.)
and conveys the fact that there is only two standard ways to represent
instances.
- Section: The Classes in the CLOS Kernel
Standard-slot-description should have a slot named "initarg".
- Section: The Named Class Definition Protocol
Why would we have to parse the slots at load time instead of compile time?
Add-named-class should be able to accept slot-descriptions as well.
Why would ADD-NAMED-CLASS call CLASS-FOR-REDEFINITION if there is no old class
object. What is the second argument supplied to CLASS-FOR-REDEFINITION in this
case? NIL?
The standard-method on add-named-class expects class-for-redefinition to
return the class to be used for the new definition.
This looks like an intangible property of CLASS-FOR-REDEFINITION as a generic
function.
- Section: The Named Method Definition Protocol
I think a template of what a DEFMETHOD would expand into would be good at this
point. The make-instance protocol for methods and generic function has to be
specified. I guess I need that to understand the following:
If defmethod is being evaluated at load time (as
opposed to compile time), the mex object is in fact the method that will
be returned by the evaluation of the defmethod form.
(defmethod expand-defmethod ((proto-method broadcast-method)
name qualifiers lambda-list body environment)
(call-next-method name qualifiers
------------------↑ proto-method should be inserted here.
(add-key-argument lambda-list '(broadcaster nil broadcast-p))
`(multiple-value-prog1 (progn ,@body)
(or broadcast-p
,(broadcast-call name lambda-list)))
environment))
- Section: The Class Update Protocol
A key property of standard classes is that they can be defined before
all their superclasses are defined.
True.
In the processing of the standard method on update-class,
direct-superclasses argument can contain symbols as well as class
objects.
I agree.
This Class Update protocol based an eager evaluation model. I want to propose a
lazy evaluation model. There is no need to propagate changes downward (to the
subclasses) if the subclasses haven't computed anything from their superclasses.
Computed properties are typically: PCL, effective slot-description, effective
default-initargs... There is no reason for computing these properties if the
class is not going have instances since a class cannot compute its
effective propeties based on the effective property of its superclasses.
I propose that the lattice structure is updated when FINALIZE-INHERITANCE is
called. PROPAGATE-CLASS-UPDATE will be called only on classes that are
fully-defined.
I also propose to get rid of forward-reference-class. The direct-supers
slot of a class is never mapped to class object. When finalize-inheritance is
called, the mapping is done in order to compute the CPL and other effective
properties but the direct-supers slot is not updated. I thinks it reflects better
what the user expects if the mapping between name and class object changes.
More next week.
Patrick.
∂07-Dec-87 1643 Common-Lisp-Object-System-mailer MOP comments part 1.
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 7 Dec 87 16:42:53 PST
Received: from Semillon.ms by ArpaGateway.ms ; 07 DEC 87 14:49:00 PST
Date: Mon, 7 Dec 87 14:47 PST
From: Gregor.pa@Xerox.COM
Subject: MOP comments part 1.
To: Patrick H Dussud <DUSSUD%jenner.csc.ti.com@RELAY.CS.NET>
cc: common-lisp-object-system@sail.stanford.edu
Fcc: BD:>Gregor>mail>outgoing-mail-1.text
In-Reply-To: <2774647634-6446503@Jenner>
Message-ID: <871207144728.3.GREGOR@SPIFF.parc.xerox.com>
Line-fold: no
Date: Fri, 4 Dec 87 17:27:14 CST
From: Patrick H Dussud <DUSSUD%jenner.csc.ti.com@RELAY.CS.NET>
I like this draft much better than the first draft that came out
last march.
Glad to hear it.
- Section: Class Organization in the CLOS Kernel
I find the argumentation in favor of common base design not very
convincing.
I agree that the argumentation presented in the current draft is not
very convinving. See below.
Having the mixins is fine if you have cut
the world exactly right for the variation of class behavior one wants.
However, if not, then one has the same type of problem with overriding
unwanted behavior with multiple mixins
I agree with this. If we think that we can't get it right in a reasonnable
amount of time, then I want to suggest an alternative:
(defclass basic-class ())
(defclass standard-allocation-class (basic-class))
(defclass structure-allocation-class (basic-class))
(defclass standard-class (standard-allocation-class) ...)
(defclass structure-class (structure-allocation-class) ...)
(defclass built-in-class (basic-class))
That's a minimal approach that preserves modularity (no turning off/on methods.)
and conveys the fact that there is only two standard ways to represent
instances.
Well, I believe that we may want to go to a structure like:
(defclass basic-class () ...)
(defclass standard-class (basic-class) ...)
(defclass structure-class (basic-class) ...)
(defclass built-in-class (basic-class) ...)
.
.
but I think doing even that will be hard in a "reasonable ampount of
time". The point is this. In this organization, what behavior do you
put in basic-class and what behavior do you put in standard-class? Can
you make a lasting, satisfying argument for that breakdown?
So far, we have been unable to come up with a division of behavior that
we can make a lasting satisfying argument for. It may be that we will
want to go to a structure like the one above, and just take a decent
crack that the division without worrying about whether the division
appears lasting.
The real question seems to be:
If you go to a separated class structure, must the division be
appropriate just for the defined classes, or must it somehow
be more 'correct' in general. That is, when making a decision
about what should go in basic-class, should that decision be
defended only with respect to the standard-class, structure-class
and built-in-class or should it somehow be reconciled with some
more abstract notion of class division.
If we only reconcile the division with respect to the existing classes,
we are a likely to get what looks like a good modularity, but as soon as
someone tries to extend it they will discover it isn't so good. On the
other hand, if we try to reconcile the division with all future programs
in mind we will never be able to do the division. Clearly we must find
a stable middle ground in this dimension. Having spent some time
pursuing several different such middle grounds, I am starting to believe
that a structure like the one I mention above is appropriate, but even
in doing that, we will have to make some design decisions which in the
future will appear more awkward than if we just have everything be a
subclass of standard-class.
- Section: The Named Class Definition Protocol
Why would we have to parse the slots at load time instead of compile time?
Add-named-class should be able to accept slot-descriptions as well.
I suppose thats true. I wouldn't expect the efficiency gain to be
tremendously significant since the slot specifiers can be canonicalized
at compile time, and there is so much other work to do.
This Class Update protocol based an eager evaluation model. I want to propose a
lazy evaluation model. There is no need to propagate changes downward (to the
subclasses) if the subclasses haven't computed anything from their superclasses.
Computed properties are typically: PCL, effective slot-description, effective
default-initargs... There is no reason for computing these properties if the
class is not going have instances since a class cannot compute its
effective propeties based on the effective property of its
superclasses.
Lazy evaluation is harder though, and this would force user mop code to
have to be able to deal with lazy evaluation. I think an appropriate
middle ground can be reached by having the full walk happen, but having
it not do all the computations (like cpl and slots) until finalize
inheritance time.
I also propose to get rid of forward-reference-class. The direct-supers
slot of a class is never mapped to class object. When finalize-inheritance is
called, the mapping is done in order to compute the CPL and other effective
properties but the direct-supers slot is not updated. I thinks it reflects better
what the user expects if the mapping between name and class object
changes.
Actually, I think the semantics of using forward referenced class
objects are much simpler and easier to define. I don't believe this
affects the naive user (defclass only) model at all (or not very much)
and it makes the sophisticated users model easier to deal with. Having
an object to represent the forward referenced class makes it possible to
store forward-declared information about that class; this makes it
possible to implement interesting behavior like the declare-optimized
example.
-------
∂07-Dec-87 2204 RPG Re: MOP comments part 1.
∂07-Dec-87 1658 bobrow.pa@Xerox.COM Re: MOP comments part 1.
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 7 Dec 87 16:58:28 PST
Received: from Cabernet.ms by ArpaGateway.ms ; 07 DEC 87 16:53:52 PST
Date: 7 Dec 87 16:52 PST
Sender: bobrow.pa@Xerox.COM
From: Danny bobrow <bobrow.pa@Xerox.COM>
Subject: Re: MOP comments part 1.
In-reply-to: Patrick H Dussud <DUSSUD%jenner.csc.ti.com@RELAY.CS.NET>'s message
of Fri, 4 Dec 87 17:27:14 CST
To: DUSSUD%jenner.csc.ti.com@RELAY.CS.NET
cc: Gregor.pa@Xerox.COM, Moon@SCRC-STONY-BROOK.ARPA,
SKeene@SCRC-STONY-BROOK.ARPA, RPG@SAIL.STANFORD.EDU, LGD@SAIL.STANFORD.EDU,
kempf%hplabsz@hplabs.hp.com, Bobrow.PA@Xerox.COM
Message-ID: <871207-165352-3822@Xerox>
I like this draft much better than the first draft that came
out last march.
Thanks. Us too.
I find the argumentation in favor of common base design not
very convincing.
The KEY point here is that we don't think that we can really get it right, and
partly right is not as reasonable as common-base. One way to think of it is
that one can think of designing a reasonable object oriented system, and then
grafting an Common Lisp on it underneath. Things would clearly be much better
if we would start over and redesign the entire system with what we know now.
Another pseudo argument is that Pierre Cointe, in designing an object system for
EuLisp has a similar structure, and he indicated tghat having this structure
should make it much easier to get agreement witht he Europeans.
But I don't find these arguments altogether convincing either, so look forward
to a more extensive discussion next week of the possible alternatives.
Why would ADD-NAMED-CLASS call CLASS-FOR-REDEFINITION if there
is no old class object. What is the second argument supplied to
CLASS-FOR-REDEFINITION in this case? NIL?
This is just a missing piece of the writeup. It doesn't call
CLASS-FOR-REDEFINITION when there is no previously defined class -- it just
creates a new class of the correct metaclass.
I also propose to get rid of forward-reference-class.
This gives names a prominence in the system that we have tried to avoid. Names
are translated to classes at the earliest possible moment.
forward-referenced-class is an easy way to capture the fact that a class is not
yet fully defined by making appropriate methods.
∂08-Dec-87 1555 Common-Lisp-Object-System-mailer MOP Comments Part 2.
Received: from RELAY.CS.NET by SAIL.STANFORD.EDU with TCP; 8 Dec 87 15:55:23 PST
Received: from relay2.cs.net by RELAY.CS.NET id ad29946; 8 Dec 87 18:36 EST
Received: from csc.ti.com by RELAY.CS.NET id an23236; 8 Dec 87 18:30 EST
Received: from Jenner by tilde id AA21850; Tue, 8 Dec 87 16:32:09 CST
Message-Id: <2774989920-10496471@Jenner>
Date: Tue, 8 Dec 87 16:32:00 CST
From: Patrick H Dussud <DUSSUD%jenner.csc.ti.com@RELAY.CS.NET>
To: common-lisp-object-system@SAIL.STANFORD.EDU
Subject: MOP Comments Part 2.
Section: The slot inheritance protocol
The generic function collect-slotds (class local-slots cpl) collects an
ordered list of effective slot descriptions for this class. It takes
the local-slots as an argument, and recursively builds up the list of
all slots that need to be in this class. It calls
compute-effective-slotd to combine multiple definitions of a single slot
found in classes on the class precedence list.
I think that the word recursively is a mistake here, The slots should be
collected from one method. If COLLECT-SLOTDS is called recursively, the
behavior of the slot collection will be distributed among the superclasses'
class. Instead, the behavior should be centralized in the original class
argument of collect-slotds. I don't know why this function needs LOCAL-SLOTS
and CPL if that's the local slots and the cpl of CLASS.
Section: The Instance Structure Protocol
I would like to see some objectives for this section:
- Do we want a metaclass writer be to able to write, portably, a new metaclass
and be able to optimize creation and slot access as much as the native
implementation of STANDARD-CLASS, or
- Do we expect the programmer to get something functional but not very
fast ?
I assume that we want to meet the first objective, because otherwise, I don't
see much value in providing something relatively complex that does not do much.
I don't have much to say about the instance allocation stuff.
About the slot access stuff:
- OPTIMIZE-INSTANCE-ACCESS that is supposed to produce optimized code for
slot-value, slot-value-using-class, their predicates and setf functions. It's
OK with me.
- STANDARD-INSTANCE-ACESS is supposed to be supplied by the implementation and
have the necessary optimization machinery so it is fast. However it works on
instance slots only. That's a bug because the method code won't know the
allocation type of a slot. A slot can be redefined in a subclass and the method
code should work for the subclass.
- STANDARD-INSTANCE-REF, called by STANDARD-INSTANCE-ACCESS has the same bug, it
accesses instance slots only. Note that this function should accept an
NOT-BOUND-FUNCTION argument, and standard-instance-access should be written
like:
(defun standard-instance-access
(instance description trap missing-function not-bound-function)
(let* ((class (class-of instance))
(index (index-in-instance class description)))
(cond ((null index)
(funcall missing-function instance description))
(t
(standard-instance-ref instance index not-bound-function)))))
Because, in order to find out if the slot is bound, STANDARD-INSTANCE-BOUNDP
has to access it.
To summarize, if we want the OPTIMIZE-INSTANCE-ACCESS method to generate a call
to a non generic, implementation optimized function, this function CANNOT infer
the allocation type of the slot from its name at compile time. This needs to be
done at runtime.
Patrick.
∂08-Dec-87 2005 Common-Lisp-Object-System-mailer MOP Comments Part 2.
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 8 Dec 87 20:04:55 PST
Received: from Semillon.ms by ArpaGateway.ms ; 08 DEC 87 19:51:54 PST
Date: Tue, 8 Dec 87 19:50 PST
From: Gregor.pa@Xerox.COM
Subject: MOP Comments Part 2.
To: Patrick H Dussud <DUSSUD%jenner.csc.ti.com@RELAY.CS.NET>
cc: common-lisp-object-system@SAIL.STANFORD.EDU
Fcc: BD:>Gregor>mail>outgoing-mail-1.text
In-Reply-To: <2774989920-10496471@Jenner>
Message-ID: <871208195028.1.GREGOR@SPIFF.parc.xerox.com>
Line-fold: no
Date: Tue, 8 Dec 87 16:32:00 CST
From: Patrick H Dussud <DUSSUD%jenner.csc.ti.com@RELAY.CS.NET>
Section: The slot inheritance protocol
The generic function collect-slotds (class local-slots cpl) collects an
ordered list of effective slot descriptions for this class. It takes
the local-slots as an argument, and recursively builds up the list of
all slots that need to be in this class. It calls
compute-effective-slotd to combine multiple definitions of a single slot
found in classes on the class precedence list.
I think that the word recursively is a mistake here,
right, the word recursively is wrong. Collect-slotds does not call
itself recursively, it goes through the cpl collecting all the slot
descriptions. We'll fix this.
I don't know why this function needs LOCAL-SLOTS
and CPL if that's the local slots and the cpl of CLASS.
Good question. I think this is holdover from an old way of doing things
or perhaps is just to make things trivially faster in PCL.
Section: The Instance Structure Protocol
I would like to see some objectives for this section:
- Do we want a metaclass writer be to able to write, portably, a new metaclass
and be able to optimize creation and slot access as much as the native
implementation of STANDARD-CLASS, or
- Do we expect the programmer to get something functional but not very
fast ?
I assume that we want to meet the first objective, because otherwise, I don't
see much value in providing something relatively complex that does
not do much.
The first objective was the one we had in mind. We will try to add some
statements that convey this.
To summarize, if we want the OPTIMIZE-INSTANCE-ACCESS method to generate a call
to a non generic, implementation optimized function, this function CANNOT infer
the allocation type of the slot from its name at compile time. This needs to be
done at runtime.
Right, I am glad you noticed this, its a horrible bug in the current
writeup. It was intended to be the way you described and in going from
whiteboard to text editor it got all screwed up. I will try to fix this
tomorrow and get out a new draft.
Patrick.
Tomorrow's draft will (hopefully) have these corrections, an improved
named-class definition protocol and an improved class update protocol.
-------
∂09-Dec-87 1006 Common-Lisp-Object-System-mailer MOP Comments (Repost)
Received: from SCORE.STANFORD.EDU by SAIL.STANFORD.EDU with TCP; 9 Dec 87 10:06:21 PST
Received: from hplabs.HP.COM by SCORE.STANFORD.EDU with TCP; Wed 9 Dec 87 09:59:39-PST
Received: from hplms2.HP.COM (hplms2) by hplabs.HP.COM with SMTP ; Wed, 9 Dec 87 10:04:57 PST
Received: from hplabsz.hpl.hp.com (hplabsz.hpl.hp.com) by hplms2.HP.COM; Wed, 9 Dec 87 10:00:40 pst
Received: from hplabsz by hplabsz; Wed, 9 Dec 87 11:00:03 pst
To: common-lisp-object-system@sail.stanford.edu
Subject: MOP Comments (Repost)
Date: Wed, 09 Dec 87 11:00:00 MST
Message-Id: <15997.566071200@hplabsz>
From: kempf%hplabsz@hplabs.HP.COM
The following are a compendium of comments from myself, Andreas Paepcke
(who has written a PCL metaclass for persistent objects) and Warren
Harris. I've also included the full text of Warren's commentary, at his
request, after the summary:
1) mixin v.s. common-base
Actually, the mixin style seems better than the common-base style, since
it partitions the state and method protocols more orthogonally, and thus
potentially avoids duplication. This seems to be moving in the direction of
method protocol classes, and classes which implement state for the
protocol. The protocol class would simply define the "external" (meaning
required to be supported) operations of the protocol, and subclasses of
the protocol class would supply specific methods (and perhaps additional
slots) which implement that protocol. In this way, it is possible to have
several implementations of a protocol and simply use type or class
predicates to test whether an object supports a protocol.
The key problem is, as Gregor noted, partitioning the protocols so that
state and function reflect what people need to extend an object-oriented
system. As Danny pointed out, it may be difficult at this time to do it
right. We already have some experience, via PCL, with the common-base
style and so can probably make a better estimate of what is needed. In
addition, Danny's comment about Pierre Cointe is relevent, since it would
be good if the ISO/EuLisp community could agree to what we come up with.
Finally, and most importantly, Danny's comment about designing an
object-oriented system and grafting Common Lisp on top is very appropriate.
With what we know now, we could certainly do better, but I don't believe
we have that option.
2) "class-prototype"
There is no explicit definition of what a class prototype is in the MOP.
Why should a class prototype be any different than an instance of a
class object of the particular metaclass required?
3) Classes in the CLOS Kernel
There is no slot for the dispatcher code in STANDARD-GENERIC-FUNCTION.
Is the idea to have different method dispatch protocols implemented by
specializing STANDARD-GENERIC-FUNCTION, with COMPUTE-DISCRIMINATOR-CODE
returning the specialized code? The problem with this is that, for
optimization purposes, it may be desirable to have the dispatcher on a
STANDARD-GENERIC-FUNCTION instance change. For example, if all the methods
on the generic function only have built-in classes as parameter specializers,
then the dispatcher need not check if the class of the arguments is a user
defined class, since, if it's not a built in class, then an error should be
signalled. This avoids the overhead of checking whether the arguments are
of a user defined class. Given the MOP as outlined in the document, the
only way this could be achieved is to have a different kind of generic
function, and that means that the generic function object would not be
EQ before and after a method which has user defined classes in the
parameter specializer list is added. One way to fix this would be to do a
CHANGE-CLASS on the generic function object, but that seems somehow
to be less than optimal, since it seems to be just fixing up the problem
afterwards.
4) Editorial Comment: Location of Named Class Definition, Slot Parsing,
and Inheritance Sections
These three sections should probably be moved so that they are in closer
proximity. Perhaps even making the slot sections a subset
of a section on named class definition, since they must logically precede
class definition. Most helpful would be a 1-2-3, step by step description
of what happens when in class defintion, and which generic functions are
involved.
5) Class and Method Definition Syntax
There is a fundamental tension in the document between the desire to
have DEFCLASS and DEFMETHOD work for user defined metaclasses
as well as the defaults, and the lack of the ability to do certain things.
Two examples:
a) Suppose I want to define a kind of slot which asks the user for a
value upon access (ASK-SLOT). Many AI languages have this kind of thing.
One way to do it would be to add a :SLOT-CLASS option to the slot-spec
syntax, but there are likely to be other areas where users will want
to make semantic extensions to class definitions, which will then need
to be reflected in the syntax.
b) Paragraph 6, pg. 3-19 implies that it is only possible to have one
method class per generic function. Presumably, a DEFGENERIC would have
to be evaluated before any method definition, in order to establish
a generic function which has a different method metaclass from the
default. There are two problems with this. One is that a generic function
is created automatically when a method is defined, but the method class
is always the default. This establishes a certain asymmetry between the
syntax of defining a method and generic function with a user defined
method metaclass and defining a class with a user defined metaclass,
and could lead to mysterious errors, should a user later
try to add a method of a user defined metaclass to an existing generic
function with methods of the default type. Secondly, it is not possible
to have a generic function with methods of more than one method class.
This tension can be resolved in a number of ways:
1) Drop the :METACLASS option for DEFCLASS and :METHOD-CLASS option for
DEFGENERIC. Thus, if people want to implement metaclasses requiring
syntactic changes will have to supply their own macros to do it. The generic
functions in the MOP should be sufficient to support this, however, and
the procedure for doing it should be outlined. The disadvantage would
be syntactic divergence between CLOS syntax and that used by implementors
of other metaclasses (but see the section below on how to handle
the default CLOS metaclasses for a possible mitigation).
2) Extend the MOP for DEFCLASS parsing and the DEFGENERIC syntax to handle
the cases outlined above (and others which could potentially be found).
Specifically, addressing a), functions for registering permitted syntactic
extensions to the DEFCLASS parser are needed. This would provide a limited
ability to extend the DEFCLASS syntax, in areas where users are most likely
to want it. Here's a shot at a specification:
ADD-DEFCLASS-SLOT-OPTION _metaclass_ _option_
Causes _option_ (a symbol) to be registered with the DEFCLASS parser
as a valid slotd option for classes of metaclass _metaclass_ (a class
object). The option will be added to the normalized slot specification
during slot parsing.
ADD-DEFCLASS-CLASS-OPTION _metaclass_ _option_
Causes _option_ (a symbol) to be registered with the DEFCLASS parser
as a valid option for classes of metaclass _metaclass_ (a class object).
The option will be added to the _options_ parameter of EXPAND-DEFCLASS.
Addressing b), the :METHOD-CLASS option of DEFGENERIC could be extended to
take a list, but this would not solve the problem with DEFMETHOD creating a
generic function having the default method class, since now the method
class would have to somehow be specified in DEFMETHOD. Another possiblility
would be to add EXPAND-DEFGENERIC-OPTIONS to the MOP:
EXPAND-DEFGENERIC-OPTIONS ((class standard-class)
name lambda-list options)
6) Code for Class/Method Definition
Why is it necessary to have a special function, ADD-NAMED-CLASS, which
instantiates a class? And ADD-NAMED-METHOD, for methods? Since classes
and methods are objects, why not simply use MAKE-INSTANCE, and put the
special processing into the INITIALIZE method? For example, the return
code for class definition would look like:
`(progn
(eval-when (compile load)
(make-instance ',(class-name (class-of prototype-instance))
:name ',name
:direct-superclasses ',direct-superclasses
:direct-slots ',direct-slots
:options ',options
:environment ',environment
)))
Metaclass users would need to implement INITIALIZE methods, but could
use CALL-NEXT-METHOD and customize.
7) Miscellaneous Class/Slot Definition
The specification of the SLOT-DESCRIPTION-CLASS generic function is
somewhat vague. By (pg. 3-21, paragraph 7):
This SLOT-DESCRIPTION-CLASS generic function is called with the
class and the normalized slot specification to determine the
class of slot description which should be produced for the class.
Does this mean that it returns the class object, so that MAKE-INSTANCE
can be called in the next step?
If so, then additional slot options should be hookable by defining
methods on SLOT-DESCRIPTION-CLASS for other metaclasses, or on individual
classes, if the metaclass is STANDARD-CLASS, as long as the syntax can
be customized.
As far as class options are concerned, what is the format and processing
sequence for DEFCLASS options? Are they passed down to EXPAND-DEFCLASS
in a list, as they appear at the end of the DEFCLASS form? Or is some
additional parsing done? If they are simply passed down as a list, with the
exception of the :METACLASS option which must be fully parsed to
instantiate the class prototype, the parser need only check if the option
is permissible. If other parsing is needed, a generic function,
EXPAND-DEFCLASS-OPTIONS, should be considered, and have a structured format
for passing the information to EXPAND-DEFCLASS. Parsing of class options
could just as well be done in EXPAND-DEFCLASS, thus centralizing class
definition in one place, but it is important that this be explicitly stated
in the document.
Re: comment about :SLOT-INITFORM-FUNCTION in the middle of pg. 3-21,
the logical place to do this is during the initialization of the slotd
object, during the MAKE-INSTANCE of the slotd object.
8) Slot Inheritence Protocol
I think an additional generic function will be needed to resolve
inheritance between slotd objects of different classes.
COMPUTE-EFFECTIVE-SLOTD calls this generic function on each
adjacent pair of slotds in the slotd list. The function must either
return one of the slotds, create another resolving the conflict, or
signal an error, if resolution is not possible. Here's a try at
an interface:
RESOLVE-SLOTD-CONFLICT ((class standard-class)
(less-specific-slotd standard-slot-description)
(more-specific-slot-description standard-slot-description))
Is there any other processing COMPUTE-EFFECTIVE-SLOTD must do besides
resolving pairwise conflicts? If not, then perhaps we only need
RESOLVE-SLOTD-CONFLICT, and COMPUTE-EFFECTIVE-SLOTD could remain hidden.
9) Way of Changing the Default Metaclasses
Some way of changing the default metaclasses for DEFCLASS, DEFGENERIC,
and DEFMETHOD is needed, so that users can simply change them when
loading a file. This would also eliminate the need for the :METACLASS
class option, although the user would have to accept the default syntax.
Two possible ways are:
a) A set of global variables, *DEFAULT-METACLASS*, *DEFAULT-SLOT-CLASS*,
*DEFAULT-GENERIC-FUNCTION-CLASS*, and *DEFAULT-METHOD-CLASS*.
b) A set of access functions which get/set these defaults in the global
environment. The function to set them could be a SETF function.
10) Protocol for Reader/Writer Functions is vague
One piece of metaobject programming which has become vital in PCLOS
(persistent CLOS) is the ability to intercept slot access, including
slot access through generated accessor functions. In the current PCL
implementation, alot of effort was needed to find out what
MAKE-READER-METHOD-FUNCTION and MAKE-WRITER-METHOD-FUNCTION do. Some
level of the slot access function's creation should be detailed, so
that metaclass programmers can customize these functions.
11) Accessing Shared Slots
Currently, the only way to access shared slots is through instances. This
leads to the cumbersome necessity of having to create an instance to
do something with class allocated slots. There should be a way to get
at this information in the metaobject protocol, so that user defined
metaclasses don't have to create instances.
12) Moving from One Level to Another in the Slot Access Protocol
The formalization of slot access levels is good, but there is a need
for a way to go from one level to another. For example, there should
be a method for getting the storage index from the slot name, given
the class, or to get a slot description from a slot index. These
methods were implemented for PCLOS, and were not hard to do, but they
seem to be logically part of the metaobject protocol.
13) Instance Structure Protocol
To motivate the following discussion, consider the following situation. I
currently have a user who is thinking of using the MOP to define a new
metaclass (C-METACLASS) which will allow creation of objects outside
of the Lisp address space. Now our garbage collector does compaction, so
Lisp objects can move when garbage is collected. This won't work for C,
but we can use bit vectors to put C objects in, since the garbage
collector doesn't look at the contents of those. The obvious way of
creating an instance of C-METACLASS is to use a bit vector with a tag in
the first word, and the C data (or pointers thereto) in the rest.
The problem with the proposed instance structure protocol is that I can't
make instances from bit vectors. Instead, I have to use one level of
indirection, making up instances from STANDARD-INSTANCE which slows down
slot access, because I need to do an additional level of indirection to
get at the data. The optional STORAGE-INFORMATION argument is insufficient,
because the entire instance must be made from a different primitive
structure than a standard instance is.
Why not arrange for the instance access and CLASS-OF protocol to accomodate
user defined instances? Here's a suggestion for a protocol:
DEFINE-METACLASS _class_ _metaclass-p_ _class-of_
Registers class _class_ as a new metaclass. _metaclass-p_ is a function
which returns T if an instance is of metaclass _class_, and _class-of_
is a function which returns the class of the instance.
STANDARD-INSTANCE-CLASS-OF _object_
STRUCTURE-INSTANCE-CLASS-OF _object_
BUILT-IN-CLASS-OF _object_
Do the obvious.
In order that instances of metaclasses other than STANDARD-CLASS can be
made from standard instances, structure instances, or anything from the
built-in types, CLASS-OF needs to check first if an instance is of a
user defined metaclass, before checking if it is one of the default
instances.
14) Instance Access Optimiztion Protocol
This should be carefully documented, as it was difficult in the PCL system
to figure out what to do.
The thought behind it is good, but the italicized comment in the middle
of pg. 3-37 sums up the problem. Currently, no way exists to tell in
Common Lisp if a particular function is executing as part of the compiler
or not. There are two ways of dealing with this (probably more):
a) The _context_ argument becomes an environmnet, and Common Lisp provides
some way of distinguishing the compile time environment. Unfortunatly,
the power in this could potentially lead to code which for which the
interpreter and compiler don't have the same semantics, contradicting one
of the design goals of Common Lisp.
b) We simply specify that all compilers must call OPTIMIZE-INSTANCE-ACCESS
at a particular optimization level, but interpreters need not. This
provides a less powerful hook, but relies on convention.
15) FORWARD-REFERENCE-CLASS
I agree with Danny and Gregor. There are some methods one may want to
define on FORWARD-REFERENCED-CLASS, if nothing other than to warn the
user that a forward referenced class is being created. Having a class
makes it more modular, since the code is concentrated in the class's
method protocol.
*********************** Warren's comments follow ******************************
My comments on the MOP (Meta-Object Protocol)
Submitted by: Warren Harris, HP Labs (harris@hplabs)
1. Nowhere does the MOP mention what this notion of a "class-prototype"
is, or why it is essential to CLOS. If it is essential, it should be
documented. If not, the specification should not be written in terms of
it. (I really think the whole notion of class prototypes should be striked
from the MOP, and viewed as an implementation detail.)
2. I still fail to see the need for special meta-object defining methods.
Why can't things like classes and methods be created by MAKE-INSTANCE, and
allow the INITIALIZE method on the meta-object to initialize that object
properly. Here is a fragment of code that I believe should work:
(defclass foo () (this))
(make-instance 'class
:name 'bar
:direct-supers (list (class-named 'foo)))
(make-instance 'bar :this 3)
In this example, everything that is necessary to make BAR a valid CLOS
class has been taken care of by the STANDARD-CLASS INITIALIZE method. This
includes computing the "effective" slot descritions (according to the
inheritance specified by COMPUTE-EFFECTIVE-SLOT-DESCRIPTION), registering
the class name on the class name table, and redefining any existing class
of the same name. (P.S. The STANDARD-CLASS INITIALIZE method should also
allow a :ENVIRONMENT init keyword, passed through by the MAKE-INSTANCE
call.)
3. I wonder if it is necessary for the extensive mechanism that expands
DEFCLASS and DEFMETHOD macros. It seems to me that there are two ways you
can view these macros: (a) as a top-level interface to creating instances
of STANDARD-CLASS and STANDARD-METHOD with no accomodation for additional
syntax that may be needed by subclasses of these meta-protocols (a user
would define new macros for radically different class creation), or (b) as
"generic" macros which may be customized to meet any meta-protocol for
defining specialized classes or methods. While the currently proposed
EXPAND-DEFCLASS method supports (b), I think that we can get a lot of
milage out of option (a) provided the macro expansions for STANDARD-CLASS
and STANDARD-METHOD are general enough. I would propose the following:
(defmacro defclass (name supers slots &rest options)
(let ((metaclass (or (getf options :metaclass)
*default-metaclass*)))
(remf options :metaclass)
(when (or (getf options :name)
(getf options :direct-supers)
(getf options :direct-slots))
(error "Invalid option in defclass."))
`(make-instance ',metaclass
:name ',name
:direct-supers (list ,@(mapcar
#'(lambda (super-name)
`(class-named ',super-name))
supers))
:direct-slots
(list ,@(mapcar #'(lambda (slot-spec)
(let* ((slot-name (first slot-spec))
(slot-options (rest slot-spec))
(slot-class (or (getf slot-options :slot-class)
*default-slot-class*)))
(remf slot-options :slot-class)
`(make-instance ',slot-class
:name ',slot-name
,@slot-options)))
slots))
,@options)))
Example:
(defclass workstation (computer commodity)
((manufacturer :initform "HP")
(model-number)
(mips :slot-class askable-slot))
:metaclass p-class
:documentation "A workstation.")
expands to:
(make-instance 'p-class
:name 'workstation
:direct-supers (list (class-named 'computer)
(class-named 'commodity))
:direct-slots (list (make-instance 'standard-slot
:name 'manufacturer
:initform "HP")
(make-instance 'standard-slot
:name 'model-number)
(make-instance 'askable-slot
:name 'mips))
:documentation "A workstation.")
Again, the STANDARD-CLASS INITIALIZE method would take care of what
ADD-NAMED-CLASS is doing now. In this defclass macro, the only reserved
words are the symbols :metaclass and :slot-class. All other options and
keywords like :initform or :accessor are simply attributes of the instances
being created. Advantages: init-plists of subclasses of standard-class and
standard-slot can be passed through the defclass form naturally.
Disadvantages: not enough protection is given to the make-instance calls
because the user could supply values to slots which should not be initable.
The second method for expanding defclass would be to go through one level
of indirection, through a generic macro-expansion function. For this I
propose something similar to what is already described, but with two levels
of parsing rather than the slot-specification normalization technique.
This way both the metaclass and the class of each slot may affect the
parsing process.
Rather than use the SLOT-DESCRIPTION-CLASS method to determine from the
normalized slot-specification the slot-descriptor class, it standardizes on
the :SLOT-CLASS keyword to extract the slot-descriptor class. (Was this
normalization process supposed to be done by the EXPAND-DEFCLASS method?
If so, users would have to reimplement that everytime they specialized
expand-defclass.) Rather than "normalizing" a slot specification, another
generic function, EXPAND-SLOT-SPECIFICATION, is called to create forms that
will make slot-description objects:
(defmacro defclass (name supers slots &rest options)
(let ((metaclass (class-named (or (getf options :metaclass)
*default-metaclass*))))
(remf options :metaclass)
(expand-defclass metaclass name supers slots options)))
where the standard-class expand-defclass method would be:
(defmethod expand-defclass ((c standard-class) name supers slots options)
(when (or (getf options :name)
(getf options :direct-supers)
(getf options :direct-slots))
(error "Invalid option in defclass."))
`(make-instance ',(class-name c)
:name ',name
:direct-supers (list ,@(mapcar
#'(lambda (super-name)
`(class-named ',super-name))
supers))
:direct-slots
(list ,@(mapcar #'(lambda (slot-spec)
(let* ((slot-name (first slot-spec))
(slot-options (rest slot-spec))
(slot-class (class-named
(or (getf slot-options :slot-class)
*default-slot-class*))))
(remf slot-options :slot-class)
(expand-slot-specification c
slot-class
slot-name
slot-options)))
slots))
,@options))
and another generic macro expansion (multi-)method would reside on
standard-slot-description to continue the expansion of the defclass:
(defmethod expand-slot-specification ((c standard-class)
(s standard-slot-description)
name
options)
(let ((reader (getf options :reader))
(accessor (getf options :accessor)))
(remf options :reader)
(remf options :accessor)
`(let ((slotd (make-instance ',(class-name s)
:name name
,@(when reader
`(:readers '(,reader)))
,@(when accessor
`(:accessors '(,accessor)))
,@options)))
,@(when reader
<code to create reader method>)
,@(when accessor
<code to create accessor method>)
slotd)))
(I'm not sure, but maybe these reader and writer methods should get
generated by the STANDARD-SLOT-DESCRIPTION INITIALIZE method, rather than
having code for them generated by the expansion of the defclass form.
That's irrelevant to the two step expansion process though.)
4. This is a suggestion. How about defining a set of global variables
which are used in the expansion of DEFCLASS, DEFGENERIC and DEFMETHOD
macros. These specify the default metaclass to instantiate when creating
classes, slots, generic-functions and methods:
(defvar *default-metaclass* 'standard-class)
(defvar *default-slot-class* 'standard-slot-description)
(defvar *default-generic-function-class* 'standard-generic-function)
(defvar *default-method-class* 'standard-method)
This way the user could bind these variables before loading a set of
definitions to control the class of what is being created without having to
physically modify each DEF<...> in the source files. For example:
(setf *default-metaclass* 'persistant-class)
(load "my-defclass-file.l")
Of course, if a :METACLASS or :SLOT-CLASS option is supplied it overrides
the default. These variables are used in macro expanding functions I've
given above.
5. I am wondering if we should allow generic-functions to contain a
non-homogeneous set of methods. The :METHOD-CLASS option seems too
restrictive. I may want to make one particular method in the
generic-function a subclass of the required method-class. For this reason,
I suggest that DEFMETHOD and DEFGENERIC-OPTIONS both allow a metaclass
option, and :METHOD-CLASS be eliminated from DEFGENERIC-OPTIONS. For
example:
(defgeneric-options doit (f)
:documentation "The DOIT generic-function does it."
:generic-function-class my-special-generic-function)
(defmethod doit ((f foo))
:method-class broadcast-method
(print 'hello))
This defines DOIT to be an instance of MY-SPECIAL-GENERIC-FUNCTION (which
is a subclass of STANDARD-GENERIC-FUNCTION), and the FOO DOIT method to be
an instance of the BROADCAST-METHOD class. The FOO DOIT method should
expand to:
(add-method (find-or-create-generic-function 'doit)
(make-instance 'broadcast-method
:name 'doit
:lambda-list '((f foo))
:body '((print 'hello))))
When no :METHOD-CLASS option is specified the value of
*DEFAULT-METHOD-CLASS* is used. The body should already be parsed by this
point by EXPAND-DEFMETHOD-BODY.
I would also suggest the addition of EXPAND-DEFGENERIC-OPTIONS to the MOP:
(defmacro defgeneric-options (name lambda-list &rest options)
(let ((metaclass (class-named (or (getf options :generic-function-class)
*default-generic-function-class*))))
(remf options :generic-function-class)
(expand-defgeneric-options metaclass name lambda-list options)))
(defmethod expand-defgeneric-options ((c standard-class)
name lambda-list options)
...)
6. Nothing seems to be said in the MOP about metaclasses compatibility. I
would hope that the following code will work:
(defclass my-class (standard-class) ())
(defclass foo () ())
(defclass bar (foo) () :metaclass my-class)
Since nothing is changed from STANDARD-CLASS to MY-CLASS, everything should
be identitical (the way instances are allocated and initialized, the way
defclass is parsed, etc.) At this point MY-CLASS should be interchangable
with STANDARD-CLASS, and therefore compatible.
7. Regarding the mixin-base vs. common-base style of defining
standard-class, I just wanted to add a few notes.
The idea of the mixin-base style intimately tying behaviors to classes is
intriguing. This seems to be moving in the direction of protocol-classes
and classes which implement that protocol. The protocol-class would simply
define the "external" (meaning required to be supported) operations of the
protocol, and subclasses of the protocol-class would supply specific
methods (and perhaps additional slots) which implement that protocol. In
this way it is possible to have several implementations of a protocol and
simply use (TYPEP <instance> <protocol-class>) to test whether an object
supports a protocol. Formally, TYPEP should probably only be used with its
second argument as a protocol-class. Protocol-classes should only inherit
from other protocol-classes, whereas implementation classes can inherit
from other implementations. Defining an implementation class only in terms
of a protocol insures that any class that implements that protocol may be
used at runtime, whereas calling methods and accessing slots of another
implementation class not included in a protocol violates encapsulation.
Protocol classes should not be instantiated directly.
I'm not proposing that protocol classes be added to the language as a first
class feature, but this is exciting because it all seems doable within the
confines of CLOS. The key question is how to partition the protocols
involved in CLOS into a well defined independent and additive set of
behaviors. Pierre Cointe's recent paper in OOPSLA-87 may shed some light
on what the minimal requirements for classes and objects are. Other
protocols are implied by the MOP: namable, forward-referencable, specific
update protocols, specific initialization protocols, etc.
The common-base style certainly eliminates the need to partition protocols,
but has what I think is one serious flaw: requiring the user to define
protocol predicates. I have found this to be a major disadvantage in
programming Common Objects which uses this mechanism. The problem is that
although the predicate can specify whether a protocol is met, it has no
inherent notion of protocol inheritance, and no way of querying an object
as to the protocols it supports.
∂09-Dec-87 1246 Common-Lisp-Object-System-mailer MOP Comments (Repost) - 2 3 4 5a
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 9 Dec 87 12:46:30 PST
Received: from Semillon.ms by ArpaGateway.ms ; 09 DEC 87 11:51:57 PST
Date: Wed, 9 Dec 87 11:48 PST
From: Gregor.pa@Xerox.COM
Subject: MOP Comments (Repost) - 2 3 4 5a
To: kempf%hplabsz@hplabs.HP.COM
cc: common-lisp-object-system@sail.stanford.edu
Fcc: BD:>Gregor>mail>outgoing-mail-1.text
In-Reply-To: <15997.566071200@hplabsz>
Message-ID: <871209114845.4.GREGOR@SPIFF.parc.xerox.com>
Line-fold: no
Date: Wed, 09 Dec 87 11:00:00 MST
From: kempf%hplabsz@hplabs.HP.COM
Thanks for your comments. There are so many of them that I won't try to
address all of them in this message. This message include comments on
points 2, 3, 4 and 5a.
2) "class-prototype"
There is no explicit definition of what a class prototype is in the MOP.
Why should a class prototype be any different than an instance of a
class object of the particular metaclass required?
This is just an omission in the current document. All a class prototype
is is an instance of the given class that can be used for method lookup.
So for example, when calling a generic function like expand-defclass,
you can use class-prototype as follows:
(expand-defclass (class-prototype (class-named 'standard-class))
'foo
'()
'((a :initform 1) (b :initform 2))
'()
'())
A legal definition of class-prototype is:
(defun class-prototype (class)
(allocate-instance class))
but the idea was that class-prototype would always pass back the same
instance again and again and in this way prevent needless consing.
3) Classes in the CLOS Kernel
There is no slot for the dispatcher code in STANDARD-GENERIC-FUNCTION.
Is the idea to have different method dispatch protocols implemented by
specializing STANDARD-GENERIC-FUNCTION, with COMPUTE-DISCRIMINATOR-CODE
returning the specialized code? The problem with this is that, for
optimization purposes, it may be desirable to have the dispatcher on a
STANDARD-GENERIC-FUNCTION instance change. For example, if all the methods
on the generic function only have built-in classes as parameter specializers,
then the dispatcher need not check if the class of the arguments is a user
defined class, since, if it's not a built in class, then an error should be
signalled. This avoids the overhead of checking whether the arguments are
of a user defined class. Given the MOP as outlined in the document, the
only way this could be achieved is to have a different kind of generic
function, and that means that the generic function object would not be
EQ before and after a method which has user defined classes in the
parameter specializer list is added. One way to fix this would be to do a
CHANGE-CLASS on the generic function object, but that seems somehow
to be less than optimal, since it seems to be just fixing up the problem
afterwards.
I guess I don't understand this point at all. I don't see the relation
between the optimization you mention and the a slot for the
discriminator code or the class of the generic function. Certainly the
discrimintor code will be computed and stored 'somewhere' in the generic
function, we just didn't see the need to specify a slot or an intrinsic
accessor for it.
It seems to me that the relevant code is:
(defmethod add-method (..)
.. (compute-discriminator-code gf) ..)
(defmethod remove-method (..)
.. (compute-discriminator-code gf) ..)
(defmethod update-generic-function (..)
.. (compute-discriminator-code gf) ..)
Given that, compute-discriminator-code can produce a piece of
discriminator code that is optimized in the ways you mentioned.
Certainly I would expect that the standard method on
compute-discriminator-code would perform this optimization.
4) Editorial Comment: Location of Named Class Definition, Slot Parsing,
and Inheritance Sections
These three sections should probably be moved so that they are in closer
proximity. Perhaps even making the slot sections a subset
of a section on named class definition, since they must logically precede
class definition. Most helpful would be a 1-2-3, step by step description
of what happens when in class defintion, and which generic functions are
involved.
In the latest draft these have been moved closer together and all the
stuff having to do with methods and generic functions was put together.
5) Class and Method Definition Syntax
I want to split this into two parts, I am only including the parts of
this that I am responding to in this message.
There is a fundamental tension in the document between the desire to
have DEFCLASS and DEFMETHOD work for user defined metaclasses
as well as the defaults, and the lack of the ability to do certain things.
Two examples:
I am only responding to the first one.
a) Suppose I want to define a kind of slot which asks the user for a
value upon access (ASK-SLOT). Many AI languages have this kind of thing.
One way to do it would be to add a :SLOT-CLASS option to the slot-spec
syntax, but there are likely to be other areas where users will want
to make semantic extensions to class definitions, which will then need
to be reflected in the syntax.
This tension can be resolved in a number of ways:
1) Drop the :METACLASS option for DEFCLASS and :METHOD-CLASS option for
DEFGENERIC. Thus, if people want to implement metaclasses requiring
syntactic changes will have to supply their own macros to do it. The generic
functions in the MOP should be sufficient to support this, however, and
the procedure for doing it should be outlined. The disadvantage would
be syntactic divergence between CLOS syntax and that used by implementors
of other metaclasses (but see the section below on how to handle
the default CLOS metaclasses for a possible mitigation).
2) Extend the MOP for DEFCLASS parsing and the DEFGENERIC syntax to handle
the cases outlined above (and others which could potentially be found).
Specifically, addressing a), functions for registering permitted syntactic
extensions to the DEFCLASS parser are needed. This would provide a limited
ability to extend the DEFCLASS syntax, in areas where users are most likely
to want it. Here's a shot at a specification:
ADD-DEFCLASS-SLOT-OPTION _metaclass_ _option_
Causes _option_ (a symbol) to be registered with the DEFCLASS parser
as a valid slotd option for classes of metaclass _metaclass_ (a class
object). The option will be added to the normalized slot specification
during slot parsing.
ADD-DEFCLASS-CLASS-OPTION _metaclass_ _option_
Causes _option_ (a symbol) to be registered with the DEFCLASS parser
as a valid option for classes of metaclass _metaclass_ (a class object).
The option will be added to the _options_ parameter of EXPAND-DEFCLASS.
Extending the defclass and slot options for a class already works. I
think the sentence "If there are any syntactic errors in the defclass
form an error is signalled" is confusing. All this sentence is saying
is that it takes the cadr of the defclass form and makes it be the name,
the caddr and its the supers, the cadddr is the slots and the cddddr is
the options. If for some reason it can't do that minimal parsing an
error is signalled.
Given that all further parsing is in the mop protocol. Extended options
are handled by the slot-parsing protocol and legal-class-option-p.
For example, to define a metaclass that supports a :slot-class slot
option:
(defclass my-class (standard-class)
())
(defmethod slot-description-class ((class my-class) specification)
(symbol-class (getf (cdr specification)
:slot-class
'standard-slot-description)))
(defclass my-slot-description (standard-slot-description)
())
(defmethod :after initialize-instance ((slotd my-slot-description)
&key slotd-class)
())
To define a metaclass that supports a new :foo class option.
(defmethod legal-class-option-p or ((class my-class) option)
(and (listp option)
(eq (car option) ':foo)))
-------
∂09-Dec-87 1344 Common-Lisp-Object-System-mailer Re: MOP Comments (Repost) - 2 3 4 5a
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 9 Dec 87 13:44:51 PST
Received: from Semillon.ms by ArpaGateway.ms ; 09 DEC 87 13:30:26 PST
Date: Wed, 9 Dec 87 13:30:12 PST
From: Ken Kahn <Kahn.pa@Xerox.COM>
Subject: Re: MOP Comments (Repost) - 2 3 4 5a
In-Reply-To: <871209114845.4.GREGOR@SPIFF.parc.xerox.com>
To: Gregor.pa@Xerox.COM
cc: kempf%hplabsz@hplabs.HP.COM, common-lisp-object-system@sail.stanford.edu
Message-ID: <871209-133026-2503@Xerox>
> A legal definition of class-prototype is:
(defun class-prototype (class)
(allocate-instance class))
Then I think prototype is lousy name for this. What is prototypical about an
unitialized instance? How about class-random-instance or class-generic-instance
or some such?
References
Gregor's message of Wed, 9 Dec 87 11:48:00 PST -- MOP Comments (Repost) - 2 3 4
5a
∂09-Dec-87 1430 Common-Lisp-Object-System-mailer Meeting next week
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 9 Dec 87 14:28:03 PST
Received: from Cabernet.ms by ArpaGateway.ms ; 09 DEC 87 14:25:02 PST
Date: 9 Dec 87 14:24 PST
Sender: bobrow.pa@Xerox.COM
From: Danny bobrow <bobrow.pa@Xerox.COM>
Subject: Meeting next week
To: common-lisp-object-system@SAIL.STANFORD.EDU
cc: bobrow.pa@Xerox.COM
Message-ID: <871209-142502-2626@Xerox>
In order for the meeting next week to be fruitful, it is necessary that people
be taking the current draft as a serious proposal. Clearly Patrick and Jim
have, but we have not heard from all of you. The last meeting was successful
because we had a set of open issues that constituted an agenda. To make such
up, it would be most useful to have comments on the current draft of the
document by Friday morning our time so we can see where there are
misunderstandings, patches to be made, and issues that need to be discussed. If
people don't have the time to do the preparation for next week's meeting, then
perhaps we should not have it, but that would be very sad.
danny
∂09-Dec-87 1456 Common-Lisp-Object-System-mailer Re: MOP Comments (Repost) - 2 3 4 5a
Received: from SCORE.STANFORD.EDU by SAIL.STANFORD.EDU with TCP; 9 Dec 87 14:56:05 PST
Received: from hplabs.HP.COM by SCORE.STANFORD.EDU with TCP; Wed 9 Dec 87 14:50:22-PST
Received: from hplms2.HP.COM (hplms2) by hplabs.HP.COM with SMTP ; Wed, 9 Dec 87 14:55:28 PST
Received: from hplabsz.hpl.hp.com (hplabsz.hpl.hp.com) by hplms2.HP.COM; Wed, 9 Dec 87 14:54:44 pst
Received: from hplabsz by hplabsz; Wed, 9 Dec 87 15:54:19 pst
To: Gregor.pa@Xerox.COM
Cc: common-lisp-object-system@sail.stanford.edu
Subject: Re: MOP Comments (Repost) - 2 3 4 5a
In-Reply-To: Your message of Wed, 09 Dec 87 11:48:00 -0800.
<871209114845.4.GREGOR@SPIFF.parc.xerox.com>
Date: Wed, 09 Dec 87 15:54:15 MST
Message-Id: <19375.566088855@hplabsz>
From: kempf%hplabsz@hplabs.HP.COM
> 3) Classes in the CLOS Kernel
> There is no slot for the dispatcher code in STANDARD-GENERIC-FUNCTION.
> Is the idea to have different method dispatch protocols implemented by
> specializing STANDARD-GENERIC-FUNCTION, with COMPUTE-DISCRIMINATOR-CODE
> returning the specialized code? The problem with this is that, for
> optimization purposes, it may be desirable to have the dispatcher on a
> STANDARD-GENERIC-FUNCTION instance change. For example, if all the methods
> on the generic function only have built-in classes as parameter specializers,
> then the dispatcher need not check if the class of the arguments is a user
> defined class, since, if it's not a built in class, then an error should be
> signalled. This avoids the overhead of checking whether the arguments are
> of a user defined class. Given the MOP as outlined in the document, the
> only way this could be achieved is to have a different kind of generic
> function, and that means that the generic function object would not be
> EQ before and after a method which has user defined classes in the>
> parameter specializer list is added. One way to fix this would be to do a
> CHANGE-CLASS on the generic function object, but that seems somehow
> to be less than optimal, since it seems to be just fixing up the problem
> afterwards.
> I guess I don't understand this point at all. I don't see the relation
> between the optimization you mention and the a slot for the
> discriminator code or the class of the generic function.
You're right, it doesn't have anything to do with this. I think there
are two issues here, one is that I somehow have this picture which says
that the dispatcher code is logically a slot in the generic function,
because it's part of it, but, taking the functional approach, the proper
set of primitives make it irrelevent if the slot is physically there or
not.
The other issue I'll address after your following set of comments.
> It seems to me that the relevant code is:
> (defmethod add-method (..)
> .. (compute-discriminator-code gf) ..)
> (defmethod remove-method (..)
> .. (compute-discriminator-code gf) ..)
> (defmethod update-generic-function (..)
> .. (compute-discriminator-code gf) ..)
> Given that, compute-discriminator-code can produce a piece of
> discriminator code that is optimized in the ways you mentioned.
> Certainly I would expect that the standard method on
> compute-discriminator-code would perform this optimization.
Yes, this will work if the implementor of CLOS implements
COMPUTE-DISCRIMINATOR-CODE with the optimizations I've outlined, but here's
another example. A user wants to implement a discrimintor which caches
and uncaches data before and after a method invocation, if the method
being invoked references a persistent object. Unless there is some interface for
generating discriminators, the only way to do this is by :BEFORE and
:AFTER methods around COMPUTE-DISCRIMINATOR-CODE, which might have to undo
things done by the primary, if the user wants to continue using the default
STANDARD-GENERIC-FUNCTION. Of course, it would be possible to say that
user accessable MOP hooks are not available at that low a level (which
essentially corresponds to hooks at the level of FUNCALLABLE-INSTANCE-CLASS).
But this example is something which came up in a real application, and
the only solution, if we wanted to continue using the standard generic
function class, we could find using the current CLOS is to define user
level :BEFORE and :AFTER daemons around *every* method which accesses
a persistent object. This seems like a less elegent solution than
providing a metaclass hook.
> Extending the defclass and slot options for a class already works. I
> think the sentence "If there are any syntactic errors in the defclass
> form an error is signalled" is confusing. All this sentence is saying
> is that it takes the cadr of the defclass form and makes it be the name,
> the caddr and its the supers, the cadddr is the slots and the cddddr is
> the options. If for some reason it can't do that minimal parsing an
> error is signalled.
What about slot parsing? Is any error checking done on the options before
calling EXPAND-DEFCLASS?
jak
∂09-Dec-87 1917 Common-Lisp-Object-System-mailer Re: MOP Comments (Repost) - 2 3 4 5a
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 9 Dec 87 19:16:06 PST
Received: from Semillon.ms by ArpaGateway.ms ; 09 DEC 87 19:08:43 PST
Date: Wed, 9 Dec 87 18:29 PST
From: Gregor.pa@Xerox.COM
Subject: Re: MOP Comments (Repost) - 2 3 4 5a
To: kempf%hplabsz@hplabs.HP.COM
cc: common-lisp-object-system@sail.stanford.edu
Fcc: BD:>Gregor>mail>outgoing-mail-1.text
In-Reply-To: <19375.566088855@hplabsz>
Message-ID: <871209182949.7.GREGOR@SPIFF.parc.xerox.com>
Line-fold: no
Date: Wed, 09 Dec 87 15:54:15 MST
From: kempf%hplabsz@hplabs.HP.COM
Yes, this will work if the implementor of CLOS implements
COMPUTE-DISCRIMINATOR-CODE with the optimizations I've outlined, but here's
another example. A user wants to implement a discrimintor which caches
and uncaches data before and after a method invocation, if the method
being invoked references a persistent object. Unless there is some interface for
generating discriminators, the only way to do this is by :BEFORE and
:AFTER methods around COMPUTE-DISCRIMINATOR-CODE, which might have to undo
things done by the primary, if the user wants to continue using the default
STANDARD-GENERIC-FUNCTION.
Well :before and :after methods on compute-discriminator-code won't do
any good since compute-discriminator-code is called at defmethod time
not generic function invocation time.
Of course, it would be possible to say that
user accessable MOP hooks are not available at that low a level (which
essentially corresponds to hooks at the level of FUNCALLABLE-INSTANCE-CLASS).
But this example is something which came up in a real application, and
the only solution, if we wanted to continue using the standard generic
function class, we could find using the current CLOS is to define user
level :BEFORE and :AFTER daemons around *every* method which accesses
a persistent object. This seems like a less elegent solution than
providing a metaclass hook.
I see. I think the real problem is that compute-effective-method-body
isn't receiving the variables which will hold the actual arguments as
arguments. In other words it doesn't have access to the same facility
make-method-call does. Suppose there were a function called
make-function-call which took one argument (a function) and called it on
the arguments received by the generic function. Like make-method-call,
these could be used in the body of effective-methods. Then you could
get the behavior you want by saying:
(defmethod compute-effective-method ((gf my-gf) ...)
`(progn ,(make-function-call #'encache-data)
,(call-next-method)
,(make-function-call #'decache-data)))
You wouldn't lose any of the performance of the native method lookup
mechanism. There wouldn't have to be :before and :after methods for
every method. This would be something that would work with any method
combination type, you could change the method combination type out from
under this and everything would still be fine.
I will try to add something like this to the next round of the mop
draft. Clearly it is important. building a better abstraction for
make-function-call and make-method-call is what is required. The
difficulty is going to be keeping the way the particular implementation
of effective methods chooses to pass around the arguments abstract.
> Extending the defclass and slot options for a class already works. I
> think the sentence "If there are any syntactic errors in the defclass
> form an error is signalled" is confusing. All this sentence is saying
> is that it takes the cadr of the defclass form and makes it be the name,
> the caddr and its the supers, the cadddr is the slots and the cddddr is
> the options. If for some reason it can't do that minimal parsing an
> error is signalled.
What about slot parsing? Is any error checking done on the options before
calling EXPAND-DEFCLASS?
No error checking is done before calling expand-defclass.
slot-description-class and the initialize-instance method for the
slot-description class do all the error checking on the slot options.
legal-class-option-p does all the error-checking on class options.
-------
∂10-Dec-87 1739 Common-Lisp-Object-System-mailer Re: Meeting next week
Received: from RELAY.CS.NET by SAIL.STANFORD.EDU with TCP; 10 Dec 87 17:38:53 PST
Received: from relay2.cs.net by RELAY.CS.NET id ae24508; 10 Dec 87 19:13 EST
Received: from csc.ti.com by RELAY.CS.NET id ap08398; 10 Dec 87 19:10 EST
Received: from Jenner by tilde id AA10333; Thu, 10 Dec 87 15:53:29 CST
Message-Id: <2775160366-4222063@Jenner>
Date: Thu, 10 Dec 87 15:52:46 CST
From: Patrick H Dussud <DUSSUD%jenner.csc.ti.com@RELAY.CS.NET>
To: common-lisp-object-system@SAIL.STANFORD.EDU
Subject: Re: Meeting next week
In-Reply-To: Msg of 9 Dec 87 14:24 PST from Danny bobrow <bobrow.pa@xerox.com>
Date: 9 Dec 87 14:24 PST
From: Danny bobrow <bobrow.pa@xerox.com>
Subject: Meeting next week
In order for the meeting next week to be fruitful, it is necessary that people
be taking the current draft as a serious proposal. Clearly Patrick and Jim
have, but we have not heard from all of you. The last meeting was successful
because we had a set of open issues that constituted an agenda. To make such
up, it would be most useful to have comments on the current draft of the
document by Friday morning our time so we can see where there are
misunderstandings, patches to be made, and issues that need to be discussed. If
people don't have the time to do the preparation for next week's meeting, then
perhaps we should not have it, but that would be very sad.
danny
I talked to David Moon last week, before he went to vacation. He told me he read
the proposal and we discussed some issues. My comments reflect this.
I thought that we were also supposed to talk about the second chapter, we need
a face to face meeting for that, so please don't give up.
Speaking of open issues, I would like to add the following to the list of open
issues for the third chapter:
- Make-instance interface for classes, generic-function, and methods.
- Compile-file behaviour and environment support.
Patrick.
∂11-Dec-87 1108 Common-Lisp-Object-System-mailer Re: Meeting next week
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 11 Dec 87 11:07:57 PST
Received: from Cabernet.ms by ArpaGateway.ms ; 11 DEC 87 10:49:45 PST
Date: 11 Dec 87 10:48 PST
Sender: bobrow.pa@Xerox.COM
From: Danny bobrow <bobrow.pa@Xerox.COM>
Subject: Re: Meeting next week
To: common-lisp-object-system@SAIL.STANFORD.EDU
Message-ID: <871211-104945-1568@Xerox>
I sent out my message of 9 Dec 87 14:24 PST to sound out people's feelings. I
have been very gratified by the encouraging responses, some sent to the whole
mailing list, and some mailed only to me personally. With such a positive sense
of the importance and timeliness of next week's meeting, I am sure it will be a
fruitful one, and am looking forward to seeing you all there.
danny
∂11-Dec-87 1300 Common-Lisp-Object-System-mailer Re: Meeting next week
Received: from SCORE.STANFORD.EDU by SAIL.STANFORD.EDU with TCP; 11 Dec 87 12:59:56 PST
Received: from hplabs.HP.COM by SCORE.STANFORD.EDU with TCP; Fri 11 Dec 87 12:54:23-PST
Received: from hplms2.HP.COM (hplms2) by hplabs.HP.COM with SMTP ; Fri, 11 Dec 87 12:59:04 PST
Received: from hplabsz.hpl.hp.com (hplabsz.hpl.hp.com) by hplms2.HP.COM; Fri, 11 Dec 87 12:58:44 pst
Received: from hplabsz by hplabsz; Fri, 11 Dec 87 13:58:24 pst
To: Danny bobrow <bobrow.pa@Xerox.COM>
Cc: common-lisp-object-system@SAIL.STANFORD.EDU
Subject: Re: Meeting next week
In-Reply-To: Your message of 11 Dec 87 10:48:00 -0800.
<871211-104945-1568@Xerox>
Date: Fri, 11 Dec 87 13:58:21 MST
Message-Id: <11063.566254701@hplabsz>
From: kempf%hplabsz@hplabs.HP.COM
Could someone send out the exact dates, times, and location of the meeting?
Thanx.
jak
∂11-Dec-87 1355 Common-Lisp-Object-System-mailer new version of mop
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 11 Dec 87 13:55:27 PST
Received: from Semillon.ms by ArpaGateway.ms ; 11 DEC 87 13:46:13 PST
Date: Fri, 11 Dec 87 13:44 PST
From: Gregor.pa@Xerox.COM
Subject: new version of mop
To: common-lisp-object-system@sail.stanford.edu
Fcc: BD:>Gregor>mail>outgoing-mail-1.text
Message-ID: <871211134433.9.GREGOR@SPIFF.parc.xerox.com>
Line-fold: no
There is a new version of the mop on sail.
-------
∂11-Dec-87 1725 Common-Lisp-Object-System-mailer Meeting Next Week
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 11 Dec 87 17:24:37 PST
Received: from Semillon.ms by ArpaGateway.ms ; 11 DEC 87 16:31:09 PST
Date: Fri, 11 Dec 87 16:29 PST
From: Gregor.pa@Xerox.COM
Subject: Meeting Next Week
To: Dick Gabriel <RPG@SAIL.Stanford.EDU>
cc: common-lisp-object-system@sail.stanford.edu
Fcc: BD:>Gregor>mail>outgoing-mail-1.text
In-Reply-To: The message of 11 Dec 87 13:12 PST from Dick Gabriel
<RPG@SAIL.Stanford.EDU>
Message-ID: <871211162924.0.GREGOR@SPIFF.parc.xerox.com>
Line-fold: no
Date: 11 Dec 87 13:12 PST
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>
My reaction to the supplied chapter 3 is mixed. Let me outline it
briefly:
As usual, I have only included the parts of your message I am actually
replying to.
(actually Danny and I both wrote this, but the current state of text
editors is such that I can't say "M-X Pluralize Author")
1. I am uncomfortable with the common-base (or subtractive) philosophy. I
believe it to be a priori incorrect though practical. I would submit for
consideration a modification, which is that the meta-object protocol be in
terms of the large classes (standard-class and friends) but that the
ontology of those classes be unspecified. That is, I think we can leave
open the question as to whether standard-class is a diamond or an
accumulation of mixins - making that an implementation choice - and also
leave open whether extensions to the protocol based on mixins from
constituent classes is possible.
As important as what is said in a specification is what is unsaid.
I think this is a good point. Certainly we could leave specific
implementations free to modularize standard class any way they want.
Also, there is no doubt that we are all uncomfortable with the
common-base design. As I have said before, the question is not "is
there something better" the question is "do we have enough experience to
come up with something better, or is that going to take a few years".
2. Although the meta-object protocol is advertised as an interpreter - which
seems to be a good presentation mechanism at least - there is no explicit
picture of what that interpreter is like. Possible situations would be
an informal description, a set of constraints, or an actual piece of
pseudo-code. Without such an overview, it is very difficult to get the
big picture from chapter 3.
Its true that chapter 3 doesn't give a very good overview. I think we
can do better than what is there. We haven't addressed that issue too
much since because we had PCL out there to do that job for us.
3. I fear that too much hidden detail exists. For example, there is a casual
mention of a ``class name table'' in the description of ADD-NAMED-CLASS. This
term is nowhere mentioned, and it is not clear whether this is a thing that
must exist in every CLOS or whether this is a device in the possibly
fictitious interpreter.
That is just symbol-class.
4. There is too little orthogonality between objects and names.
ADD-NAMED-CLASS would seem to require a name and a class as arguments, yet
it takes a prototype instance, a name, and a bunch of stuff for making up
a class. I would have guessed that ADD-NAMED-CLASS is a combination of
UPDATE-CLASS and something else. The fact that it might be necessary to
package name and object handling into one place strikes me as a hint
of tangled design.
I believe the distinction between classes and names is quite well drawn.
The reason add-named-class has such a complex behavior is because it
must implement the semantics of:
(if <class-exists-p>
<update it as described in chapter 1>
<define a new one as described in chapter 1>)
The layer underneath the named layer deals with the class and generic
function objects anonymously. Except for the generic functions for
which it is explicitly stated that they deal with names, they all deal
with anonymous objects. Anything that can be done with a named object
can be done with an anonymous object, including the find and update
protocol which defclass provides for named objects.
5. The existence of prototype instances all over gives me the feeling that
the descriptive mechanism for methods is poor. It appears that these
prototypes mostly solve the problem of arranging for a method on some
superclass to be selectable where (defethod f ((class (eql C1))...) would
not work. Since we have dirtied the language with EQL already, how about
(defmethod foo ((class (at-most C1)))...) which means that CLASS must be
a class that is either C1 or a subclass of C1?
Right. I think we have all known for some time that sometimes 'dummy'
arguments are passed to methods to make the method lookup work. Thats
why we added the feature to defmethod to make specialized arguments be
'referred to'. We could consider adding this new kind of specializer
now, but I think its a little late in the game for that. Prototype
instances, even though a little ugly, are simple and work.
7. My impression is that the proposed protocols are good for making
OOP systems that are almost exactly like CLOS but bad for anything
different. The subtractive philosophy advertises that.
Well, we have a fair amount of empirical evidence that suggests that
this protocol can be used to make systems that are fairly different than
CLOS. I think we got a pretty clear inidication of that at the OOPSLA
workshop. There is also a fair amount of other work we have seen that
reinforces this. That work has had a significant influence on this
design, we believe the design outlined in chapter 3 is much better than
the design currently implemented in PCL.
Of course there is the question of what 'almost exactly like CLOS' and
'fairly different than CLOS' mean. Clearly there must be many systems
that no metaobject protocol we could write would provide adequate
support for.
8. Of course we need better names for things than names like Collect-slotDs.
But I suspect that DannyB and GregorK won't object.
Of course.
10. Too much emphasis has gone into making portable implementations of
CLOS possible. Because there is no portable way to extend the Common Lisp
type system doesn't mean that we must outlaw things that could be done in
a Common Lisp in which that is possible. There must be a careful
distinction made between the mistakenly requiring as portable things that
are non-portable on one hand, and foolishly prohibiting things that are
not portable.
The last paragraph in the introduction to the Instance Structure Protocol
section is an example of this.
I believe that what you are saying is that it should be legal for a
specific implementation to define its own mechanisms for extending the
unerlying type system. I agree. I just don't think we can add to
Common Lisp something that gives users that power since it also gives
them the power to destroy the entire type system.
-------
∂12-Dec-87 0128 Common-Lisp-Object-System-mailer Meeting Next Week
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 12 Dec 87 01:28:47 PST
Received: from JUNCO.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 300662; Fri 11-Dec-87 10:35:53 EST
Date: Fri, 11 Dec 87 10:35 EST
From: Sonya E. Keene <skeene@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Meeting Next Week
To: common-lisp-object-system@SAIL.STANFORD.EDU
cc: skeene@STONY-BROOK.SCRC.Symbolics.COM
Message-ID: <19871211153545.4.SKEENE@JUNCO.SCRC.Symbolics.COM>
Yesterday I sent a message about this, but I don't think it got through.
We had an impressive power glitch. The mail log claimed that my
message was sent successfully, but I never got my copy back from sail.
So, this might be a repeat of a previous message, but it might not.
Oh well.
For any of you who are wondering if we Symbolians are taking the
Meta-object proposal seriously, the answer is yes. We were very
pleased to see the draft, which is much more comprehensive than the
previous draft. Dave has not responded on the mail because he is on
vacation. I am not ready to respond with comments yet, because I need
some time to read the draft thoroughly and think about it. Keep in
mind that this is a lot of new stuff.
Certainly we should have the meeting. First of all, we need to
finalize and agree on the Chapters 1 and 2, so we can distribute them to
X3J13 as soon as possible. Also, I had hoped we could talk about
constructors in person. And now that we have a Meta-object Proposal,
we have a good basis for discussion on that as well.
I also want to give my opinion on productive meetings. Our meeting in
Palo Alto was productive because we were nearly in agreement on a number
of small issues. Each person took charge of some issues, and we
discussed them and made decisions on them. I think the discussion on
the Meta-object Protocol will be productive in a different way, more
like our July meeting in Cambridge. At that meeting we concentrated
on initialization (one large topic) and talked about it until we
identified the major framework of it, the procedural definition. That
meeting was not as highly structured as the other meeting, but we got
good results.
I have confidence that our meeting next week can be productive in the
same way. Along with finalizing Chapters 1 and 2, we have two primary
tasks: 1. reaching agreement on the technical issues of the
Meta-object protocol, and then 2. turning the current proposal into the
usual dry, factual tone of the rest of the specification. (Yes, we'll
probably have to take out most of those funny lines.) I'm sure that
Dave is eager to make some real progress on the Meta-object protocol, as
am I. I'm also willing to help out with the writing.
∂12-Dec-87 1235 Common-Lisp-Object-System-mailer Comments on MOP
To: Common-lisp-object-system@SAIL.Stanford.EDU
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>
The following is a part of a message to a subset of the readers of
this list (which contained other comments) concerning my reaction to
the proposed chapter 3.
My reaction to the supplied chapter 3 is mixed. Let me outline it briefly:
1. I am uncomfortable with the common-base (or subtractive) philosophy. I
believe it to be a priori incorrect though practical. I would submit for
consideration a modification, which is that the meta-object protocol be in
terms of the large classes (standard-class and friends) but that the
ontology of those classes be unspecified. That is, I think we can leave
open the question as to whether standard-class is a diamond or an
accumulation of mixins - making that an implementation choice - and also
leave open whether extensions to the protocol based on mixins from
constituent classes is possible.
As important as what is said in a specification is what is unsaid.
2. Although the meta-object protocol is advertised as an interpreter - which
seems to be a good presentation mechanism at least - there is no explicit
picture of what that interpreter is like. Possible situations would be
an informal description, a set of constraints, or an actual piece of
pseudo-code. Without such an overview, it is very difficult to get the
big picture from chapter 3.
One might argue that PCL fills that gap for now, but I don't believe we
should rely on a difficult-to-read piece of code to understand the
details of a proposal.
3. I fear that too much hidden detail exists. For example, there is a casual
mention of a ``class name table'' in the description of ADD-NAMED-CLASS. This
term is nowhere mentioned, and it is not clear whether this is a thing that
must exist in every CLOS or whether this is a device in the possibly
fictitious interpreter.
4. There is too little orthogonality between objects and names.
ADD-NAMED-CLASS would seem to require a name and a class as arguments, yet
it takes a prototype instance, a name, and a bunch of stuff for making up
a class. I would have guessed that ADD-NAMED-CLASS is a combination of
UPDATE-CLASS and something else. The fact that it might be necessary to
package name and object handling into one place strikes me as a hint
of tangled design.
Since it appears that this is intended to model the semantics of
DEFCLASS when re-defining a class, perhaps it's better for the
expansion of DEFCLASS to be
...(if <class-with-this-name-exists-p>
<update the definition>
<create a class and install it>)
rather than having a function that embodies this code.
I suppose I never got over the dislike I had for the decision to
require DEFCLASS to preserve EQness upon redefinition. I suppose the
decision is still a reasonable one because it is too much work to
consider a change in the class hierarchy to be a change to some of the
generic functions defined on it, thereby invoking the generic-function-changed
protocol.
5. The existence of prototype instances all over gives me the feeling that
the descriptive mechanism for methods is poor. It appears that these
prototypes mostly solve the problem of arranging for a method on some
superclass to be selectable where (defmethod f ((class (eql C1))...) would
not work. Since we have dirtied the language with EQL already, how about
(defmethod foo ((class (at-most C1)))...) which means that CLASS must be
a class that is either C1 or a subclass of C1?
6. I didn't see a clear set of mechanisms for optimizing anonymous classes
along the lines of the example piece of code in the section on
CLASS-FOR-REDEFINITION. Are anonymous objects too faceless in this
specification?
7. My impression is that the proposed protocols are good for making
OOP systems that are almost exactly like CLOS but bad for anything
different. The subtractive philosophy advertises that.
8. Of course we need better names for things than names like Collect-slotDs.
But I suspect that DannyB and GregorK won't object.
9. The section on Instance Structure Protocol seems too wedded to
a structure-like representation. Depending on how specific the
interpreter presentation will be, it might make sense to be a little
more abstract about the nature of the mappings from slots to representation.
10. Too much emphasis has gone into making portable implementations of
CLOS possible. Because there is no portable way to extend the Common Lisp
type system doesn't mean that we must outlaw things that could be done in
a Common Lisp in which that is possible. There must be a careful
distinction made between the mistakenly requiring as portable things that
are non-portable on one hand, and foolishly prohibiting things that are
not portable.
The last paragraph in the introduction to the Instance Structure Protocol
section is an example of this.
11. The generic-function-changed protocol does not specify the definition
of a generic function change - when is this protocol triggered?
-rpg-
∂13-Dec-87 2138 Common-Lisp-Object-System-mailer Further Reaction to MOP
To: common-lisp-object-system@SAIL.Stanford.EDU
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>
In my last message I expressed some concerns about the proposed
meta-object protocol. In this message I will express one of those concerns
more clearly. Lest anyone begin to fear that I oppose the proposal, let me
hasten to remark that I believe we need to know as precisely as we can the
limitations of any meta-object protocol before we adopt it.
When Gregor first explained to me his philosophy of the meta-object
protocol - before the draft was available - he said that it was the set of
objects on which the metacircular interpreter for CLOS operated. He went
on to say that the MOP would talk about a set of generic functions,
methods on which could be defined along with other meta-objects to modify
the behavior of the interpreter. I took this a little too literally and
concluded that a ``meta-object'' is either one of these generic functions
or one of the objects on which those generic functions operated. Thus, the
meta-object protocol was a set of objects, a set of generic functions, and
a set of relationships among when and how those generic functions were
invoked. In other words, to specify the protocol, one had to specify
those three things.
Gregor corrected me on this, and I learned that the generic functions and
the relationships among when and how they were invoked were the protocol,
and that the meta-objects are defined separately. To alter the style of
the object system, one needed to define new meta-objects and new methods
on those generic functions operating on those new meta-objects.
This led me to believe that the generic functions would be truly generic,
extracting information out of the meta-objects to determine further actions.
That is, I imagined that it was intended that any wild variant on
CLOS could be created with the definition of some wild meta-objects and
methods on the supplied generic functions.
Well, maybe you can do that, but the generic functions in the current
protocol have too many assumptions built into them.
I assume that all variants on CLOS definable with the meta-object protocol
should include: classes, generic functions, inheritance, instantiation,
and methods. I assume some variants might not include: frame/slot
structure, qualifiers on methods, named objects, multiple inheritance, or
linearized inheritance.
Some of the generic functions in the MOP don't seem to follow a strong
decompositional structure. For instance, ADD-NAMED-CLASS perforce assumes
that classes can be named, and its definition has built in the assumption
of the existence of slots. To a lesser degree its definition has built in the
assumption of multiple inheritance.
The existence of CLASS-FOR-REDEFINITION is built on the assumption
of the behavior of EQness over redefinitions. EXPAND-DEFMETHOD has built
in assumptions about qualifiers, EXPAND-DEFMETHOD has built in assumptions
about slots, options, and multiple inheritance.
If I were to build a variant on CLOS, I would abandon the current naming
scheme and use normal Lisp binding for naming. I would also probably
define a graph manipulation language and attach classes to the graph. An
explicit finalization protocol would optimize method lookup, etc.
Finally, I would add some encapsulation technology, probably abandoning
the current frame/slot format for instances. Therefore, many of the
generic functions in this protocol are irrelevant to me.
Now, there is nothing wrong with having generic functions in the protocol
that have the various assumptions about the nature of the object-oriented
language built in, but I would have assumed that generic functions that
knew about these assumptions would be found in the information stored in
the metaclass and would have no names associated with them. The
meta-object protocol would extract these functions and apply them.
The heart of the meta-object protocol seems to be parsing and creation.
Parsing of forms should be a simple matter of the user-level macro
invoking a parser from the correct metaclass. Because we have such a
complex and powerful MAKE-INSTANCE protocol, I thought that the
meta-object protocol would be built on it, and, in fact, that
MAKE-INSTANCE would be formalized and be made the mainstay of the
meta-object protocol - it would represent the primary interpreter. Recall
that there is a powerful technique for initialization to cause arguments
to be passed to allocation and initialization generic functions at various
times. I would have expected to see a protocol that looked like that and
was, therefore, more declarative in nature, putting information in
metaclasses to be extracted by methods on INITIALIZE-INSTANCE and
ALLOCATE-INSTANCE for those metaclasses. This would eliminate the need for
a wide variety of generic functions with a host of parameters that are too
specific to the default nature of CLOS.
For example, naming classes is an example of invoking a different
ALLOCATE-INSTANCE method and a different INITIALIZE-INSTANCE method.
What we have, instead, is a fairly ad hoc protocol. That is, it seems
that if one were to want to define a very different object-oriented
language - one in which there are no frame/slot-like structures, a
graph-oriented inheritance structure, mixed representations - one would
have to build a separate connected component to the hierarchy and define
another set of generic functions to handle the protocol.
Now, it might turn out that the initialization protocol is not good enough
to form the basis of the meta-object protocol, but attempting to use it as
such a basis would be a good test of it. And even though using the
initialization protocol would not simplify the situation much, it would
certainly unify it.
-rpg-
∂14-Dec-87 0727 Common-Lisp-Object-System-mailer meeting next week
Received: from SCRC-RIVERSIDE.ARPA by SAIL.STANFORD.EDU with TCP; 14 Dec 87 07:27:32 PST
Received: from JUNCO.SCRC.Symbolics.COM by Riverside.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 208926; Thu 10-Dec-87 10:54:21 EST
Date: Thu, 10 Dec 87 10:53 EST
From: Sonya E. Keene <skeene@STONY-BROOK.SCRC.Symbolics.COM>
Subject: meeting next week
To: common-lisp-object-system@SAIL.STANFORD.EDU
Message-ID: <19871210155358.5.SKEENE@JUNCO.SCRC.Symbolics.COM>
Danny,
I haven't read your message yet because my file server is down.
But I heard that you're considering not having our Working Group
meeting next week because you don't believe all of us are taking
the Meta-object proposal seriously enough.
Dave has read the proposal, but he's away on vacation this week,
so he won't be able to give any written comments by tomorrow
morning. As for myself, I am in the process of reading the
proposal, with the goal of understanding it as best I can by the
time of the meeting. Remember, this is all new stuff and we need
some time to digest it.
About productive meetings: our meeting in Palo Alto was
productive because we were very close to reaching consensus on a
number of small issues. Each person took charge of a set of
issues, we discussed them, and we made decisions. I think our
first meeting on the Meta-object protocol will be productive in a
different way, more like our July meeting in Cambridge. At
that meeting we concentrated on one large topic -- Initialization
-- until we worked out the major framework of it.
I believe our discussion about the Meta-object protocol will be
productive because you have given us a much more comprehensive
proposal than we have seen before.
However, there are other reasons why it is necessary to meet. We
weren't quite ready to distribute Chapters 1 and 2 for the last
X3J13 meeting, because we didn't have time to sit down and be sure
that the new format of the function descriptions was correct in
every point. It's very important that our group carefully
reviews that draft and formally agrees that it's ready to
distribute. Also, we haven't had a chance to discuss
constructors as a group. We intended to do that in Fort Collins,
but at the last minute our Group meeting was canceled.
In summary, I believe it is very important that we meet next week,
and I have every reason to believe the meeting will be productive.
Please don't take the lack of immediate response from us
Symbolians as implying we aren't taking your proposal seriously.
We were very glad to see a detailed written proposal. I see two
major tasks ahead: 1. getting consensus from the Working Group
about the technical aspects of the Meta-object Protocol, and
filling in all the gaps, and 2. turning the proposal into the
appropriate language for the specification. We are eager to
participate in Task 1, and I'd like to help out with Task 2 as
well.
Sonya
∂14-Dec-87 2109 Common-Lisp-Object-System-mailer new version of mop
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 14 Dec 87 21:09:05 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 303192; Tue 15-Dec-87 00:08:18 EST
Date: Tue, 15 Dec 87 00:08 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: new version of mop
To: Gregor.pa@Xerox.COM
cc: common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: <871211134433.9.GREGOR@SPIFF.parc.xerox.com>
Message-ID: <19871215050814.7.MOON@EUPHRATES.SCRC.Symbolics.COM>
Line-fold: No
Date: Fri, 11 Dec 87 13:44 PST
From: Gregor.pa@Xerox.COM
There is a new version of the mop on sail.
The version of sail:mop.tex[cls,lsp] written 11 Dec 13:43 has obviously
never been run through TEX, or else you changed the macros.tex file
but forgot to update it on SAIL.
∂15-Dec-87 1004 Common-Lisp-Object-System-mailer
Received: from AI.AI.MIT.EDU by SAIL.STANFORD.EDU with TCP; 15 Dec 87 10:04:09 PST
Date: Tue, 15 Dec 87 13:01:57 EST
From: "Gregor J. Kiczales" <GREGOR@AI.AI.MIT.EDU>
To: common-lisp-object-system@SAIL.STANFORD.EDU
Message-ID: <299924.871215.GREGOR@AI.AI.MIT.EDU>
There is now a file on sail called macros.new. This fileis only
slightly different, so it surprises me that the old macros file didn't
work. It may mean that this one won't work either..
∂18-Dec-87 1558 Common-Lisp-Object-System-mailer MOP Goals
Received: from SCORE.STANFORD.EDU by SAIL.STANFORD.EDU with TCP; 18 Dec 87 15:56:16 PST
Received: from hplabs.HP.COM by SCORE.STANFORD.EDU with TCP; Fri 18 Dec 87 15:50:31-PST
Received: from hplms2.HP.COM (hplms2) by hplabs.HP.COM with SMTP ; Fri, 18 Dec 87 15:56:18 PST
Received: from hplabsz.hpl.hp.com (hplabsz.hpl.hp.com) by hplms2.HP.COM; Fri, 18 Dec 87 15:55:59 pst
Received: from hplabsz by hplabsz; Fri, 18 Dec 87 16:55:38 pst
To: common-lisp-object-system@sail.stanford.edu
Subject: MOP Goals
Date: Fri, 18 Dec 87 16:55:36 MST
Message-Id: <25918.566870136@hplabsz>
From: kempf%hplabsz@hplabs.HP.COM
As a result of last week's meeting, would it be possible to consider revising
the goals of the MOP in the direction of more modesty?
As was discussed, the MOP faces the twin dangers of tying the CLOS
implementor's hands (making it difficult to provide a high performance
implementation by opening the kernel up too far) and not providing enough
functionality for extending CLOS in radically different directions.
For the next five years or so, the most likely uses of the MOP seem to
be as hooks for program development environments and modest extensions
of CLOS (persistence, frame-based languages). Perhaps, if we focused on
those, we could achieve a useful standard, which would still allow research
into how metaclass programming should be done.
jak
∂18-Dec-87 1609 Common-Lisp-Object-System-mailer Versioning
Received: from SCORE.STANFORD.EDU by SAIL.STANFORD.EDU with TCP; 18 Dec 87 16:09:09 PST
Received: from hplabs.HP.COM by SCORE.STANFORD.EDU with TCP; Fri 18 Dec 87 16:03:30-PST
Received: from hplms2.HP.COM (hplms2) by hplabs.HP.COM with SMTP ; Fri, 18 Dec 87 16:09:15 PST
Received: from hplabsz.hpl.hp.com (hplabsz.hpl.hp.com) by hplms2.HP.COM; Fri, 18 Dec 87 16:08:55 pst
Received: from hplabsz by hplabsz; Fri, 18 Dec 87 17:08:12 pst
To: common-lisp-object-system@sail.stanford.edu
Subject: Versioning
Date: Fri, 18 Dec 87 17:08:09 MST
Message-Id: <26090.566870889@hplabsz>
From: kempf%hplabsz@hplabs.HP.COM
One of the topics discussed at the meeting last week was versioning. I
have given some thought to this, and I think a better way to it would
be to use something like Stan Zdonick's VERSIONED-OBJECT class as a
metaclass, from which all versioned classes and versioned instances
are created. Instances would have a write through cache which contained
the current slot value, and writes to slots would cause updates to
a data structure (AVL-DAG's are nice) which maintained the different
versions of slot values. This protocol could be implemented with
SLOT-VALUE-USING-CLASS.
Changes in slots could be maintained in a similar fashion, except
UPDATE-INSTANCE-STRUCTURE, ADD-NAMED-CLASS, and CLASS-FOR-REDEFINITION
would have to be modified to cause the newly updated class to store
added and deleted slots in a data structure and similarly for the
slot values in instances.
As far as methods go, as with STANDARD-CLASS, all the old ones would
apply, though the class update protocol could be modified to check for
cases where modifications are needed.
jak
∂19-Dec-87 0925 Common-Lisp-Object-System-mailer Versioning
Received: from [128.81.41.109] by SAIL.STANFORD.EDU with TCP; 19 Dec 87 09:25:23 PST
Received: from CHICOPEE.SCRC.Symbolics.COM by ALDERAAN.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 153032; Sat 19-Dec-87 12:25:21 EST
Date: Sat, 19 Dec 87 12:26 EST
From: Daniel L. Weinreb <DLW@ALDERAAN.SCRC.Symbolics.COM>
Subject: Versioning
To: kempf%hplabsz@hplabs.HP.COM, common-lisp-object-system@sail.stanford.edu
In-Reply-To: <26090.566870889@hplabsz>
Message-ID: <19871219172631.2.DLW@CHICOPEE.SCRC.Symbolics.COM>
Date: Fri, 18 Dec 87 17:08:09 MST
From: kempf%hplabsz@hplabs.HP.COM
One of the topics discussed at the meeting last week was versioning. I
have given some thought to this, and I think a better way to it would
be to use something like Stan Zdonick's VERSIONED-OBJECT class as a
metaclass, from which all versioned classes and versioned instances
are created. Instances would have a write through cache which contained
the current slot value, and writes to slots would cause updates to
a data structure (AVL-DAG's are nice) which maintained the different
versions of slot values. This protocol could be implemented with
SLOT-VALUE-USING-CLASS.
That's interesting. We have something very much like this in Statice.
In fact, it is called versioned-entity. We implement it with macros;
that is, you don't just say DEFCLASS (what you really don't say is
DEFFLAVOR, but you know what I mean) but you say DEFINE-ENTITY-TYPE, and
it expands into a lot of stuff including little caching accessor
methods, a DEFFLAVOR with extra instance variables to hold the cache
validation state, and so on.
I'd like to find out more about Zdonik's VERSIONED-OBJECT class. Is
this written up anywhere, or is source code available, or anything like
that? Thanks.
∂19-Dec-87 1047 Common-Lisp-Object-System-mailer Re: Versioning
Received: from SCORE.STANFORD.EDU by SAIL.STANFORD.EDU with TCP; 19 Dec 87 10:47:34 PST
Received: from hplabs.HP.COM by SCORE.STANFORD.EDU with TCP; Sat 19 Dec 87 10:41:55-PST
Received: from hplms2.HP.COM (hplms2) by hplabs.HP.COM with SMTP ; Sat, 19 Dec 87 10:47:46 PST
Received: from hplabsz.hpl.hp.com (hplabsz.hpl.hp.com) by hplms2.HP.COM; Sat, 19 Dec 87 10:47:23 pst
Received: from hplabsz by hplabsz; Sat, 19 Dec 87 11:47:03 pst
To: "Daniel L. Weinreb" <DLW@ALDERAAN.SCRC.Symbolics.COM>
Cc: common-lisp-object-system@sail.stanford.edu
Subject: Re: Versioning
In-Reply-To: Your message of Sat, 19 Dec 87 12:26:00 -0500.
<19871219172631.2.DLW@CHICOPEE.SCRC.Symbolics.COM>
Date: Sat, 19 Dec 87 11:46:59 MST
Message-Id: <6552.566938019@hplabsz>
From: kempf%hplabsz@hplabs.HP.COM
> I'd like to find out more about Zdonik's VERSIONED-OBJECT class. Is
> this written up anywhere, or is source code available, or anything like
> that? Thanks.
The paper in which Stan described VERSIONED-OBJECT came from some of
his earlier work (1985) and was from a symposium for which no proceedings
were published. Stan has refined this somewhat, and the following two
references describe the refinement:
"Maintaining Consistency in a Database with Changing Types", Stanley B.
Zdonik, SIGPLAN Notices, V21, #10, October, 1986, pp. 120-127.
"The Management of changing Types in an Object-Oriented Database,"
Andrea H. Skarra and Stanley B. Zdonik, OOPSLA 86 Proceedings, pp. 483-491.
Essentially, the refinement consists of viewing a versioned object as
a version set, with additions only on one end. A versioned set interface
is also defined for types (or classes, in CLOS terminology). A CLOS
metaclass could be used to implement the versioned sets, with the MOP
providing a level of abstraction which makes versioned objects look like
regular ones.
As far as source code goes, last I heard (in June), Stan was distributing his
persistent object system, but I think it is pretty specific to Suns
since I think he implemented a device driver to improve database access
performance. It's also written in C and comes as part of the Garden
programming environment. His net address is sbz%brown@csnet-relay.
jak
∂19-Dec-87 1059 Common-Lisp-Object-System-mailer MOP and Inheritance
Received: from SCORE.STANFORD.EDU by SAIL.STANFORD.EDU with TCP; 19 Dec 87 10:59:34 PST
Received: from hplabs.HP.COM by SCORE.STANFORD.EDU with TCP; Sat 19 Dec 87 10:53:49-PST
Received: from hplms2.HP.COM (hplms2) by hplabs.HP.COM with SMTP ; Sat, 19 Dec 87 10:59:42 PST
Received: from hplabsz.hpl.hp.com (hplabsz.hpl.hp.com) by hplms2.HP.COM; Sat, 19 Dec 87 10:59:23 pst
Received: from hplabsz by hplabsz; Sat, 19 Dec 87 11:59:04 pst
To: common-lisp-object-system@sail.stanford.edu
Subject: MOP and Inheritance
Date: Sat, 19 Dec 87 11:59:01 MST
Message-Id: <6724.566938741@hplabsz>
From: kempf%hplabsz@hplabs.HP.COM
If support for radically different kinds of inheritance is to be one of the
MOP goals, and the purpose of the tendency in the current MOP proposal to
empahsize the CPL is for maintaining Common Lisp subtyping
semantics, then it would probably rather be a better idea to fix SUBTYPEP
than to force implementors to think in terms of the CPL. This could be
achieved, for example, by making SUBTYPEP generic, and making it part
of the MOP. Note that this need not affect method dispatch, since TYPEP need
not use SUBTYPEP, and, in fact, method dispatch need not use TYPEP either.
Alternatively, the goals of the MOP could be narrowed to just supporting
inheritance consistent with current Common Lisp subtyping, and require
users wanting to do anything really different to roll their own.
jak
∂19-Dec-87 1100 Common-Lisp-Object-System-mailer Re: Versioning
Received: from SCORE.STANFORD.EDU by SAIL.STANFORD.EDU with TCP; 19 Dec 87 11:00:25 PST
Received: from hplabs.HP.COM by SCORE.STANFORD.EDU with TCP; Sat 19 Dec 87 10:54:44-PST
Received: from hplms2.HP.COM (hplms2) by hplabs.HP.COM with SMTP ; Sat, 19 Dec 87 10:51:00 PST
Received: from hplabsz.hpl.hp.com (hplabsz.hpl.hp.com) by hplms2.HP.COM; Sat, 19 Dec 87 10:50:38 pst
Received: from hplabsz by hplabsz; Sat, 19 Dec 87 11:50:17 pst
To: "Daniel L. Weinreb" <DLW@stony-brook.SCRC.Symbolics.COM>
Cc: common-lisp-object-system@sail.stanford.edu
Subject: Re: Versioning
Date: Sat, 19 Dec 87 11:50:14 MST
Message-Id: <6597.566938214@hplabsz>
From: kempf%hplabsz@hplabs.HP.COM
> I'd like to find out more about Zdonik's VERSIONED-OBJECT class. Is
> this written up anywhere, or is source code available, or anything like
> that? Thanks.
The paper in which Stan described VERSIONED-OBJECT came from some of
his earlier work (1985) and was from a symposium for which no proceedings
were published. Stan has refined this somewhat, and the following two
references describe the refinement:
"Maintaining Consistency in a Database with Changing Types", Stanley B.
Zdonik, SIGPLAN Notices, V21, #10, October, 1986, pp. 120-127.
"The Management of changing Types in an Object-Oriented Database,"
Andrea H. Skarra and Stanley B. Zdonik, OOPSLA 86 Proceedings, pp. 483-491.
Essentially, the refinement consists of viewing a versioned object as
a version set, with additions only on one end. A versioned set interface
is also defined for types (or classes, in CLOS terminology). A CLOS
metaclass could be used to implement the versioned sets, with the MOP
providing a level of abstraction which makes versioned objects look like
regular ones.
As far as source code goes, last I heard (in June), Stan was distributing his
persistent object system, but I think it is pretty specific to Suns
since I think he implemented a device driver to improve database access
performance. It's also written in C and comes as part of the Garden
programming environment. His net address is sbz%brown@csnet-relay.
jak
------- End of Forwarded Message
∂21-Dec-87 1953 Common-Lisp-Object-System-mailer MOP and Inheritance
Received: from LABREA.STANFORD.EDU by SAIL.STANFORD.EDU with TCP; 21 Dec 87 19:51:32 PST
Received: by labrea.stanford.edu; Sun, 20 Dec 87 03:41:35 PST
Received: from bhopal.lucid.com by edsel id AA29446g; Mon, 21 Dec 87 08:09:59 PST
Received: by bhopal id AA06141g; Mon, 21 Dec 87 08:11:15 PST
Date: Mon, 21 Dec 87 08:11:15 PST
From: Jon L White <edsel!jonl@labrea.stanford.edu>
Message-Id: <8712211611.AA06141@bhopal.lucid.com>
To: labrea!kempf!hplabs.HP.COM@labrea.stanford.edu
Cc: labrea!common-lisp-object-system%sail@labrea.stanford.edu
In-Reply-To: kempf%hplabsz@hplabs.HP.COM's message of Sat, 19 Dec 87 11:59:01 MST <6724.566938741@hplabsz>
Subject: MOP and Inheritance
How would you propose to generalize SUBTYPEP, so that making it generic
would be useful? Unlike TYPEP, it operates only on type "names", rather
than on random objects. The current name spectrum only includes symbols
and and certain list constructs over them; e.g.
VECTOR
NEW-DEFSTRUCT-KIND
(ARRAY SINGLE-FLOAT *)
(OR INTEGER FLOAT)
and so on.
-- JonL --
∂22-Dec-87 1514 Common-Lisp-Object-System-mailer Re: MOP and Inheritance
Received: from LABREA.STANFORD.EDU by SAIL.STANFORD.EDU with TCP; 22 Dec 87 15:14:29 PST
Received: from Score.Stanford.EDU by labrea.stanford.edu with TCP; Tue, 22 Dec 87 15:14:32 PST
Received: from hplabs.HP.COM by SCORE.STANFORD.EDU with TCP; Tue 22 Dec 87 14:53:27-PST
Received: from hplms2.HP.COM (hplms2) by hplabs.HP.COM with SMTP ; Tue, 22 Dec 87 14:57:58 PST
Received: from hplabsz.hpl.hp.com (hplabsz.hpl.hp.com) by hplms2.HP.COM; Tue, 22 Dec 87 14:57:34 pst
Received: from hplabsz by hplabsz; Tue, 22 Dec 87 15:57:13 pst
To: Jon L White <edsel!jonl@labrea.stanford.edu>
Cc: labrea!kempf!hplabs.HP.COM@labrea.stanford.edu,
labrea!common-lisp-object-system%sail@labrea.stanford.edu
Subject: Re: MOP and Inheritance
In-Reply-To: Your message of Mon, 21 Dec 87 08:11:15 -0800.
<8712211611.AA06141@bhopal.lucid.com>
Date: Tue, 22 Dec 87 15:57:08 MST
Message-Id: <6052.567212228@hplabsz>
From: kempf%hplabsz@hplabs.hp.com
> How would you propose to generalize SUBTYPEP, so that making it generic
> would be useful? Unlike TYPEP, it operates only on type "names", rather
> than on random objects. The current name spectrum only includes symbols
> and and certain list constructs over them; e.g.
> VECTOR
> NEW-DEFSTRUCT-KIND
> (ARRAY SINGLE-FLOAT *)
> (OR INTEGER FLOAT)
> and so on.
I believe part of the CLOS spec states that class objects are to become
valid wherever Common Lisp currently takes type specifiers. Thus, SUBTYPEP
will have to take classes in addition to symbols and lists in any case.
Making SUBTYPEP generic would allow metaclass programmers to define
their own subtyping relationships, rather than being bound to that
currently in Common Lisp. This could free up the need to specify the
CPL data structure as part of the metaobject protocol, opening up the
the metaobject protocol to supporting implementation of metaclasses with
radically different kinds of inheritance.
This is not to say that SUBTYPEP *should* be made generic, since, given
the current state of knowledge about how to construct a metaclass kernel,
it's not clear what else might be needed to support implementation of
radically different kinds of inheritance.
jak
∂22-Dec-87 1819 Common-Lisp-Object-System-mailer with-accessors
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 22 Dec 87 18:19:46 PST
Received: from Cabernet.ms by ArpaGateway.ms ; 22 DEC 87 18:20:58 PST
Date: Tue, 22 Dec 87 18:18 PST
From: Gregor.pa@Xerox.COM
Subject: with-accessors
To: common-lisp-object-system@SAIL.STANFORD.EDU
Fcc: BD:>Gregor>mail>outgoing-mail-1.text
Message-ID: <871222181857.7.GREGOR@SPIFF.parc.xerox.com>
Line-fold: no
I presented the current state of CLOS to the people at MCC. When I got
to with-slots they said "hey thats biased against accessors". We came
up with the idea of with-accessors which is basically like the long form
of with slots.
This use of with-accessors:
(with-accessors ((x position-x)
(y position-y))
p1
(setq x y))
is equivalent to:
(let ((#:g1 p1))
(setf (position-x #:g1) (position-y #:g1)))
and is parallel to:
(with-slots ((x x)
(y y))
p1
(setq x y))
I think the MCC comment was good and captures a lot of the complaints I
have heard about the new with-slots. I think we should add
with-accessors to the spec.
-------
∂23-Dec-87 1307 Common-Lisp-Object-System-mailer add-method when method exists
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 23 Dec 87 13:06:52 PST
Received: from Semillon.ms by ArpaGateway.ms ; 23 DEC 87 13:06:51 PST
Date: Wed, 23 Dec 87 13:04 PST
From: Gregor.pa@Xerox.COM
Subject: add-method when method exists
To: common-lisp-object-system@SAIL.STANFORD.EDU
Fcc: BD:>Gregor>mail>outgoing-mail-1.text
Message-ID: <871223130432.9.GREGOR@SPIFF.parc.xerox.com>
Line-fold: no
In the current version of the spec, if add-method is used to add a
method to a generic function and there is already a method with the same
specializers and qualifiers and error is signaled. I think thats a bad
idea, I think it should just remove the old method and add the new one.
Note that it should NOT call remove-method to remove the old one.
The reason is that very often you want to replace an existing method
with a new method. Take the following example:
(defmethod foo :before ((x object)) 'before)
(defmethod foo ((x object)) 'primary)
If I want to redefine the second method, I want to replace it with the
new method, I don't want to first remove the old method because if I do,
the generic function will be in an illegal state (it will have no
primary method).
-------
∂23-Dec-87 1436 Common-Lisp-Object-System-mailer New Class Organization for CLOS Kernel
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 23 Dec 87 14:35:50 PST
Received: from Cabernet.ms by ArpaGateway.ms ; 23 DEC 87 14:36:19 PST
Date: 23 Dec 87 14:34 PST
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: New Class Organization for CLOS Kernel
To: common-lisp-object-system@SAIL.STANFORD.EDU
Message-ID: <871223-143619-8688@Xerox>
The following is my understanding of what we agreed to in Cambridge.
Principles:
1) We specify as disjoint the metaclasses that support built in classes,
structure classes and standard classes.
2) We provide classes in the lattice that support certain type determinations.
These type specifying classes will usually have no methods specified as
specialized to them in the kernel. (A possible exception is standard-object,
which is a guaranteed superclass of all instances that have standard-class as
their metaclass)
3) We specify links only as subclass relations rather than direct subclass
relations, allowing implementations freedom to organize code sharing.
Result:
The following is a mapping of the class lattice. Indentation is used to
indicate subclass relationships. Class names surround by <..> indicate classes
used for type determination. In general, these "taxonomic" classes are abstract
classes in the sense that they are not expected to be instantiated.
If the metaclass of a class is not standard-class, that metaclass is shown in
(...).
T (built-in-class)
<standard-object>
<generic-function>
standard-generic-function (funcallable-standard-class)
<method>
standard-method
standard-accessor-method
standard-reader-method
standard-writer-method
<slot-description>
standard-slot-description
standard-class-slot-description
standard-structure-slot-description
<class>
standard-class
forward-referenced-class
funcallable-standard-class
built-in-class
structure-class
A link not shown in the diagram is the subclass link from generic-fucntion to
function.
----- End Forwarded Messages -----
danny
∂23-Dec-87 1444 Common-Lisp-Object-System-mailer reinitialize-instance
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 23 Dec 87 14:44:02 PST
Received: from Cabernet.ms by ArpaGateway.ms ; 23 DEC 87 14:39:08 PST
Date: 23 Dec 87 14:37 PST
From: Bobrow.pa@Xerox.COM
Subject: reinitialize-instance
To: common-lisp-object-system@SAIL.STANFORD.EDU
Message-ID: <871223-143908-8700@Xerox>
It was suggested that there be a general facility in CLOS to reinitialize an
instance. It would then be used for updating classes and generic functions.
The following is a strawman proposal for the standard method for
reinitialize-instance.
(defmethod reinitialize-instance
((instance standard-object) &rest reinit-args &key &allow-other-keys)
(apply #'initialize-instance
(default-initargs (class-of instance) reinit-args)))
This uses the code for initialize-instance to do whatever it would ordinarily
do, using the standard defaulting method for the arguments. It also allows
users to write :before and :after methods on reinitialize-instance to take
special actions for reinitialization.
Potential problems
1) There is no argument legality checking.
2) reinitialize-instance does not see the defaulted list of initargs
∂23-Dec-87 1454 Common-Lisp-Object-System-mailer Concep.tex
To: common-lisp-object-system@SAIL.Stanford.EDU
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>
This file is now available on SAIL. It is the latest revision based on
the Decemeber Cambridge meeting. It should be nearly the last version.
-rpg-
∂23-Dec-87 1458 Common-Lisp-Object-System-mailer Proposed New Outline For MOP Kernel
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 23 Dec 87 14:58:04 PST
Received: from Cabernet.ms by ArpaGateway.ms ; 23 DEC 87 14:53:49 PST
Date: 23 Dec 87 14:48 PST
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Proposed New Outline For MOP Kernel
To: common-lisp-object-system@SAIL.STANFORD.EDU
Message-ID: <871223-145349-8721@Xerox>
Class Lattice in the Kernel
Anonymous Class Manipulation Protocol
Making New Classes
make-instance 'standard-class
make-instance 'standard-slot-description
make-instance 'standard-reader-method
make-instance 'standard-writer-method
slot-description-class
reader-method-class
writer-method-class
legal-class-option-p
legal-slot-option-p
check-superclass-legality (formerly check-super-metaclass-compatibility)
compute-direct-superclasses (formerly default-class-supers)
Class Inheritance
compute-class-precedence-list
collect-slot-descriptions
computive-effective-slot-description
finalize-inheritance
Class Updating
class-for-redefinition
compatible-metaclass-change-p
reinitialize-instance 'standard-class
notify-this-class-on-update
propagate-class-update
update-class-locally
class-has-instances-p
make-instances-obsolete
Named Class Manipulation
expand-defclass
add-named-class
symbol-class
cboundp
class-name
Instance Structure Protocol (* New Proposal Coming *)
Slot Level Protocol
slot-value-using-class ... (or slot-value ...)
allocate-instance
Symbol Storage Level Protocol
storage-slot-using-class ... (or %slot-value ...)
allocate-standard-instance-storage(slot-description-list ...)
Optimized Slot Access
...
Anonymous Generic Functions
Creating generic Functions
make-instance 'standard-generic-function
generic-function
Updating generic Functions
reinitialize-instance 'standard-generic-function
Method Combination
compute-discriminator-code
compute-effective-method
...
Named Generic Functions
ensure-generic-function
generic-labels
generic-flet
with-added-methods
Anonymous Methods
make-instance 'standard-method
expand-method-body
add-method-on-specializer
remove-method-on-specializer
Named Methods
expand-defmethod
∂23-Dec-87 1539 Common-Lisp-Object-System-mailer New Specializers For CLOS
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 23 Dec 87 15:38:56 PST
Received: from Cabernet.ms by ArpaGateway.ms ; 23 DEC 87 15:35:15 PST
Date: 23 Dec 87 15:33 PST
From: Bobrow.pa@Xerox.COM
Subject: New Specializers For CLOS
To: common-lisp-object-system@SAIL.STANFORD.EDU
Message-ID: <871223-153515-8767@Xerox>
There are two "hacks" in the current writeup of the MOP designed to make the
current generic function specializer mechanisms work in two special cases.
The current argument specializers in CLOS use either the identity of argument to
a given object, or membership in a set defined by the type(s) of the instance.
Two extensions have been suggested: basing method selection on a subclass
(subtype) relationship directly for class objects; and basing method selection
on the metaclass of a particular argument.
1) Choosing a method based on the instance metaclass
Current Hack:
The specification notes that (slot-value instance slot-name) is converted to
(slot-value-using-class class instance slot-name). This conversion allows the
metaclass of the instance to play a role in the selection of the method used.
Proposal:
Add a specializer form
(metaclass <class>)
A method with such a specializer would be applicable if the metaclass of the
object bound to the argument is of type specified by <class>.
Example:
(defmethod slot-value ((instance (metaclass 'standard-class)) slot-name) ...)
would allow slot-value to be a generic function whose method selection involves
the metaclass.
Issues:
a) Should <class> be a form to be evaluated, or a class-name.
Proposal: It should be a form that should evaluate to any type specifier
b) All methods specialized on a generic function must agree on whether the class
or metaclass of a particular argument is to be used for discrimination. How
should this be noted in the generic function?
Proposal: A generic function argument list can contain a require argument that
looks like (metaclass <argument name>).
2) Choosing a method based on a subclass relationship
Current Hack:
The current metaclass protocol uses a "prototype instance" to select a method in
certain cases where the identity of the particular instance is not important.
It is used because one cannot specify a method somehow associated with the class
that will be slected by an argument that is that class or a subclass.
Proposal:
Add a specializer
(subclass <class>)
A method with a subclass specializer on an argument is applicable if the
argument is of type <class> and is a subtype of the given class.
Example:
(defmethod class-expand-defclass
((class (subclass 'standard-class)) defclass-form) ...)
will choose the expansion method based on the class specified as a metaclass.
Issues: Same as for metaclass, and with corresponding answers.
------
ARGUMENTS FOR THE CHANGE
This is an obvious extension of current practice,
based on the "set" semantics of types.
It does not cost much code in the kernel.
It allows elimination of a couple of "hacks" in the current kernel
ARGUMENTS AGAINST THE CHANGE
The current hacks work.
This effects chapters 1 and 2.
People have not had much experience with these kind of features
(They second has been used quite successfully in KEE)
∂24-Dec-87 1638 Common-Lisp-Object-System-mailer CALL-NEXT-METHOD Winter Solstice present
Received: from SCORE.STANFORD.EDU by SAIL.STANFORD.EDU with TCP; 24 Dec 87 16:38:19 PST
Received: from hplabs.HP.COM by SCORE.STANFORD.EDU with TCP; Thu 24 Dec 87 16:33:56-PST
Received: from hplms2.HP.COM (hplms2) by hplabs.HP.COM with SMTP ; Thu, 24 Dec 87 16:38:37 PST
Received: from hplabsz.hpl.hp.com (hplabsz.hpl.hp.com) by hplms2.HP.COM; Thu, 24 Dec 87 16:38:12 pst
Received: from hplabsz by hplabsz; Thu, 24 Dec 87 17:37:48 pst
To: common-lisp-object-system@sail.stanford.edu
Cc: olthoff%hplms2@hplabs.HP.COM, kempf%hplms2@hplabs.HP.COM
Subject: CALL-NEXT-METHOD Winter Solstice present
Date: Thu, 24 Dec 87 17:37:45 MST
Message-Id: <28652.567391065@hplabsz>
From: kempf%hplabsz@hplabs.HP.COM
Here we go again.
We redid the algebraic specification for CALL-NEXT-METHOD to include arguments,
as the current draft of the spec allows, and the wording of the spec seems
to allow too much latitude in the semantics. The current spec says this
(pg. 2-9 in my copy):
When CALL-NEXT-METHOD is called with arguments, the next method
is called with those arguments. When providing arguments to
CALL-NEXT-METHOD, the following rule must be satisfied or an
error is signaled: The ordered set of methods applicable for a
changed set of arguments for CALL-NEXT-METHOD must be the same
as the ordered set of applicable methods for the original
arguments to the generic function. Optimizations of the error
checking are possible, but they must be invisible to the
programmer.
The problem is that there is no precise definition of what "next" method
means in this context.
Consider the following example. A generic function, GF is invoked with
the argument list AL. The computation of the effective method yields
the list of applicable methods ( M(0) M(1) M(2) M(3) M(4) ). For
simplicity's sake, say that they are all primary methods (i.e. no
daemon methods).
Say that M(0) invokes CALL-NEXT-METHOD with no arguments, M(1) does
also, and M(2) invokes CALL-NEXT-METHOD with precisely the arguments
which it was passed. The sorted list of applicable methods won't
change, but the "next" method will be M(0), since it is the next
matching method on the list.
Now say that M(2) invokes CALL-NEXT-METHOD with a list of arguments,
the classes of which match the parameter specializers for M(1). The
sorted list of applicable methods for this call is a truncated version
of that for the original invocation (the CDR, in fact). Would that be
an error? If not, then, again, the matching method would be one more
specialized rather than more general.
Neither of these cases are forbidden by the wording of the document.
We need a definition of "next" method, and I think a conservative
extension of the semantics in the nonargument case suggests that
the list of applicable methods in the execution envrionment (what
I mentioned at Boston) only include more general methods than the
currently executing one. Thus, CALL-NEXT-METHOD could only call
more general methods.
jak
∂28-Dec-87 0631 Common-Lisp-Object-System-mailer Re: add-method when method exists
Received: from [128.89.1.216] by SAIL.STANFORD.EDU with TCP; 28 Dec 87 06:31:26 PST
To: Gregor.pa@XEROX.COM
cc: common-lisp-object-system@SAIL.STANFORD.EDU
Subject: Re: add-method when method exists
In-reply-to: Your message of Wed, 23 Dec 87 13:04:00 -0800.
<871223130432.9.GREGOR@SPIFF.parc.xerox.com>
Date: Mon, 28 Dec 87 09:25:57 -0500
From: kanderso@WILMA.BBN.COM
Date: Wed, 23 Dec 87 13:04 PST
From: Gregor.pa@XEROX.COM
Subject: add-method when method exists
To: common-lisp-object-system@SAIL.STANFORD.EDU
Message-ID: <871223130432.9.GREGOR@SPIFF.parc.xerox.com>
In the current version of the spec, if add-method is used to add a
method to a generic function and there is already a method with the same
specializers and qualifiers and error is signaled. I think thats a bad
idea, I think it should just remove the old method and add the new one.
Note that it should NOT call remove-method to remove the old one.
The reason is that very often you want to replace an existing method
with a new method. Take the following example:
(defmethod foo :before ((x object)) 'before)
(defmethod foo ((x object)) 'primary)
If I want to redefine the second method, I want to replace it with the
new method, I don't want to first remove the old method because if I do,
the generic function will be in an illegal state (it will have no
primary method).
-------
I agree that an error should not be signaled, but i don't see anything
wrong with calling REMOVE-METHOD. I see nothing illegl about a
generic function without a primary method, and regularly define
protocols that have no primary methods just :AFTER methods.
∂28-Dec-87 0632 Common-Lisp-Object-System-mailer Re: add-method when method exists
Received: from [128.89.1.216] by SAIL.STANFORD.EDU with TCP; 28 Dec 87 06:32:25 PST
To: Gregor.pa@XEROX.COM
cc: common-lisp-object-system@SAIL.STANFORD.EDU
Subject: Re: add-method when method exists
In-reply-to: Your message of Wed, 23 Dec 87 13:04:00 -0800.
<871223130432.9.GREGOR@SPIFF.parc.xerox.com>
Date: Mon, 28 Dec 87 09:26:37 -0500
From: kanderso@WILMA.BBN.COM
Date: Wed, 23 Dec 87 13:04 PST
From: Gregor.pa@XEROX.COM
Subject: add-method when method exists
To: common-lisp-object-system@SAIL.STANFORD.EDU
Message-ID: <871223130432.9.GREGOR@SPIFF.parc.xerox.com>
In the current version of the spec, if add-method is used to add a
method to a generic function and there is already a method with the same
specializers and qualifiers and error is signaled. I think thats a bad
idea, I think it should just remove the old method and add the new one.
Note that it should NOT call remove-method to remove the old one.
The reason is that very often you want to replace an existing method
with a new method. Take the following example:
(defmethod foo :before ((x object)) 'before)
(defmethod foo ((x object)) 'primary)
If I want to redefine the second method, I want to replace it with the
new method, I don't want to first remove the old method because if I do,
the generic function will be in an illegal state (it will have no
primary method).
-------
I agree that an error should not be signaled, but i don't see anything
wrong with calling REMOVE-METHOD. I see nothing illegl about a
generic function without a primary method, and regularly define
protocols that have no primary methods just :AFTER methods.
∂28-Dec-87 0903 Common-Lisp-Object-System-mailer CALL-NEXT-METHOD Winter Solstice present
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 28 Dec 87 09:03:29 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 310936; Mon 28-Dec-87 12:03:45 EST
Date: Mon, 28 Dec 87 12:03 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: CALL-NEXT-METHOD Winter Solstice present
To: kempf%hplabsz@hplabs.HP.COM
cc: common-lisp-object-system@SAIL.STANFORD.EDU, olthoff%hplms2@hplabs.HP.COM
In-Reply-To: <28652.567391065@hplabsz>
Message-ID: <19871228170333.7.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Thu, 24 Dec 87 17:37:45 MST
From: kempf%hplabsz@hplabs.HP.COM
We redid the algebraic specification for CALL-NEXT-METHOD to include arguments,
as the current draft of the spec allows, and the wording of the spec seems
to allow too much latitude in the semantics. The current spec says this
(pg. 2-9 in my copy):
When CALL-NEXT-METHOD is called with arguments, the next method
is called with those arguments. When providing arguments to
CALL-NEXT-METHOD, the following rule must be satisfied or an
error is signaled: The ordered set of methods applicable for a
changed set of arguments for CALL-NEXT-METHOD must be the same
as the ordered set of applicable methods for the original
arguments to the generic function. Optimizations of the error
checking are possible, but they must be invisible to the
programmer.
The problem is that there is no precise definition of what "next" method
means in this context.
Consider the following example. A generic function, GF is invoked with
the argument list AL. The computation of the effective method yields
the list of applicable methods ( M(0) M(1) M(2) M(3) M(4) ). For
simplicity's sake, say that they are all primary methods (i.e. no
daemon methods).
Say that M(0) invokes CALL-NEXT-METHOD with no arguments, M(1) does
also, and M(2) invokes CALL-NEXT-METHOD with precisely the arguments
which it was passed. The sorted list of applicable methods won't
change, but the "next" method will be M(0), since it is the next
matching method on the list.
I think you misunderstand the description of CALL-NEXT-METHOD. Whether
or not arguments are supplied to it does not change what method it calls.
The next method is M(3) regardless of anything M(2) may do.
Evidently we need to change the documentation to say explicitly that
"next method" means the same thing in this context as in the other
context.
Now say that M(2) invokes CALL-NEXT-METHOD with a list of arguments,
the classes of which match the parameter specializers for M(1). The
sorted list of applicable methods for this call is a truncated version
of that for the original invocation (the CDR, in fact). Would that be
an error?
It would signal an error. The documentation seems quite clear on this.
If not, then, again, the matching method would be one more
specialized rather than more general.
Neither of these cases are forbidden by the wording of the document.
We need a definition of "next" method, and I think a conservative
extension of the semantics in the nonargument case suggests that
the list of applicable methods in the execution envrionment (what
I mentioned at Boston) only include more general methods than the
currently executing one. Thus, CALL-NEXT-METHOD could only call
more general methods.
I prefer the definition that the documentation is intended to say now,
which is that CALL-NEXT-METHOD calls the same method regardless of
what arguments you give it, and the arguments you give it are not
allowed to change the applicable methods. That seems simpler than a
more relaxed definition that tries to state which cases of changing
the applicable methods are allowed and which aren't, and in what
circumstances CALL-NEXT-METHOD calls a different method from the
one it would normally call.
∂28-Dec-87 1053 Common-Lisp-Object-System-mailer Re: CALL-NEXT-METHOD Winter Solstice present
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 28 Dec 87 10:53:13 PST
Received: from Cabernet.ms by ArpaGateway.ms ; 28 DEC 87 10:43:45 PST
Date: 27 Dec 87 14:00 PST
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Re: CALL-NEXT-METHOD Winter Solstice present
In-reply-to: kempf%hplabsz@hplabs.HP.COM's message of Thu, 24 Dec 87 17:37:45
MST
To: kempf%hplabsz@hplabs.HP.COM
cc: common-lisp-object-system@sail.stanford.edu, olthoff%hplms2@hplabs.HP.COM,
kempf%hplms2@hplabs.HP.COM
Message-ID: <871228-104345-1119@Xerox>
We redid the algebraic specification for CALL-NEXT-METHOD to
include arguments, as the current draft of the spec allows, and the
wording of the spec seems to allow too much latitude in the
semantics. The current spec says this (pg. 2-9 in my copy):
When CALL-NEXT-METHOD is called with arguments, the
next method is called with those arguments. When providing
arguments to CALL-NEXT-METHOD, the following rule must be
satisfied or an error is signaled: The ordered set of methods
applicable for a changed set of arguments for CALL-NEXT-METHOD
must be the same as the ordered set of applicable methods for
the original arguments to the generic function. Optimizations
of the error checking are possible, but they must be invisible
to the programmer.
The problem is that there is no precise definition of what
"next" method means in this context.
This paragraph is taken out of context. The "next" method is always the same
(defined in the purpose section of the writeup). There is a list of methods
determined by the initial arguments to the combined method. The next method is
determined by the order of methods in this list (ordered from most to least
specific). The next method is always the method in the list after the method
containing the call to call-next-method.
The intent of the paragraph above is to indicate that if arguments are provided
to call-next-method, the list of applicable methods, and order of specificity
must be the same as the original list. This preserves the semantics of the
call. The next method after the one containing the call to call-next-method in
the original list of applicable methods will be identical to one determined the
same way from a newly computed list. NOTE call-next-method never can call a
method earlier on that list.
Consider the following example. A generic function, GF is
invoked with the argument list AL. The computation of the effective
method yields the list of applicable methods ( M(0) M(1) M(2) M(3)
M(4) ). For simplicity's sake, say that they are all primary
methods (i.e. no daemon methods).
Say that M(0) invokes CALL-NEXT-METHOD with no arguments, M(1)
does also, and M(2) invokes CALL-NEXT-METHOD with precisely the
arguments which it was passed. The sorted list of applicable
methods won't change, but the "next" method will be M(0), since it
is the next matching method on the list.
Wrong. It will be M(2). Remember the rule is the same as it was earlier.
Now say that M(2) invokes CALL-NEXT-METHOD with a list of
arguments, the classes of which match the parameter specializers
for M(1). The sorted list of applicable methods for this call is a
truncated version of that for the original invocation (the CDR, in
fact). Would that be an error?
YES. It is just this case that the paragraph in question was trying to outlaw.
∂28-Dec-87 1053 Common-Lisp-Object-System-mailer Re: New Specializers For CLOS
Received: from SCORE.STANFORD.EDU by SAIL.STANFORD.EDU with TCP; 28 Dec 87 10:53:46 PST
Received: from hplabs.HP.COM ([15.255.16.7].#Internet) by SCORE.STANFORD.EDU with TCP; Mon 28 Dec 87 10:40:02-PST
Received: from hplms2.HP.COM (hplms2) by hplabs.HP.COM with SMTP ; Mon, 28 Dec 87 10:39:29 PST
Received: from hplabsz.hpl.hp.com (hplabsz.hpl.hp.com) by hplms2.HP.COM; Mon, 28 Dec 87 10:39:07 pst
Received: from hplabsz by hplabsz; Mon, 28 Dec 87 11:38:48 pst
To: Bobrow.pa@Xerox.COM
Cc: common-lisp-object-system@SAIL.STANFORD.EDU
Subject: Re: New Specializers For CLOS
In-Reply-To: Your message of 23 Dec 87 15:33:00 -0800.
<871223-153515-8767@Xerox>
Date: Mon, 28 Dec 87 11:38:45 MST
Message-Id: <12119.567715125@hplabsz>
From: kempf%hplabsz@hplabs.HP.COM
> Proposal:
> Add a specializer form
> (metaclass <class>)
> A method with such a specializer would be applicable if the metaclass of the
> object bound to the argument is of type specified by <class>.
> Proposal:
> Add a specializer
> (subclass <class>)
> A method with a subclass specializer on an argument is applicable if the
> argument is of type <class> and is a subtype of the given class.
The outlined problems are largely in Chapter 3 and the suggested
solution will impact Chapters 1 & 2 as well. It might be better to
look for a solution which does not impact Chapters 1 & 2, to avoid
having to retrofit the changes.
Since one of the characteristics of these new specializers outlined in the
proposal was that all methods on a generic function must
agree on these new specializers (i.e. either have them or the regular set,
but not both), a new class of generic function is suggested
and, with it, perhaps a set of associated macros
(DEFINE-METACLASS-METHOD ?) for conveniently defining the methods.
jak
∂28-Dec-87 1053 Common-Lisp-Object-System-mailer Re: with-accessors
Received: from SCORE.STANFORD.EDU by SAIL.STANFORD.EDU with TCP; 28 Dec 87 10:53:51 PST
Received: from hplabs.HP.COM ([15.255.16.7].#Internet) by SCORE.STANFORD.EDU with TCP; Mon 28 Dec 87 10:42:53-PST
Received: from hplms2.HP.COM (hplms2) by hplabs.HP.COM with SMTP ; Mon, 28 Dec 87 10:43:24 PST
Received: from hplabsz.hpl.hp.com (hplabsz.hpl.hp.com) by hplms2.HP.COM; Mon, 28 Dec 87 10:43:04 pst
Received: from hplabsz by hplabsz; Mon, 28 Dec 87 11:42:45 pst
To: Gregor.pa@Xerox.COM
Cc: common-lisp-object-system@SAIL.STANFORD.EDU
Subject: Re: with-accessors
In-Reply-To: Your message of Tue, 22 Dec 87 18:18:00 -0800.
<871222181857.7.GREGOR@SPIFF.parc.xerox.com>
Date: Mon, 28 Dec 87 11:42:42 MST
Message-Id: <12194.567715362@hplabsz>
From: kempf%hplabsz@hplabs.HP.COM
>
> I presented the current state of CLOS to the people at MCC. When I got
> to with-slots they said "hey thats biased against accessors". We came
> up with the idea of with-accessors which is basically like the long form
> of with slots.
> This use of with-accessors:
> (with-accessors ((x position-x)
> (y position-y))
> > p1
> (setq x y))
> is equivalent to:
> (let ((#:g1 p1))
> (setf (position-x #:g1) (position-y #:g1)))
> and is parallel to:
> (with-slots ((x x)
> (y y))
> p1
> (setq x y))
> I think the MCC comment was good and captures a lot of the complaints I
> have heard about the new with-slots. I think we should add
> with-accessors to the spec.
The sounds good.
jak
∂28-Dec-87 1108 Common-Lisp-Object-System-mailer Re: CALL-NEXT-METHOD Winter Solstice present
Received: from SCORE.STANFORD.EDU by SAIL.STANFORD.EDU with TCP; 28 Dec 87 11:08:36 PST
Received: from hplabs.HP.COM ([15.255.16.7].#Internet) by SCORE.STANFORD.EDU with TCP; Mon 28 Dec 87 09:22:22-PST
Received: from hplms2.HP.COM (hplms2) by hplabs.HP.COM with SMTP ; Mon, 28 Dec 87 09:22:21 PST
Received: from hplabsz.hpl.hp.com (hplabsz.hpl.hp.com) by hplms2.HP.COM; Mon, 28 Dec 87 09:21:59 pst
Received: from hplabsz by hplabsz; Mon, 28 Dec 87 10:21:40 pst
To: "David A. Moon" <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Cc: kempf%hplabsz@hplabs.HP.COM, common-lisp-object-system@SAIL.STANFORD.EDU,
olthoff%hplms2@hplabs.HP.COM
Subject: Re: CALL-NEXT-METHOD Winter Solstice present
In-Reply-To: Your message of Mon, 28 Dec 87 12:03:00 -0500.
<19871228170333.7.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Mon, 28 Dec 87 10:21:37 MST
Message-Id: <11302.567710497@hplabsz>
From: kempf%hplabsz@hplabs.HP.COM
> I prefer the definition that the documentation is intended to say now,
> which is that CALL-NEXT-METHOD calls the same method regardless of
> what arguments you give it, and the arguments you give it are not
> allowed to change the applicable methods. That seems simpler than a
> more relaxed definition that tries to state which cases of changing
> the applicable methods are allowed and which aren't, and in what
> circumstances CALL-NEXT-METHOD calls a different method from the
> one it would normally call.
I don't have any problem with this, except that it shuts off a potentially
nice way of using CALL-NEXT-METHOD, namely to invoke a more general
method which is not specifically the next method in the list of applicable
methods. I've often felt the need for this when using CALL-NEXT-METHOD in PCL.
However, the flexibility might not be worth trying to enumerate the
cases which will and won't work, as Dave has pointed out.
In any case, the description in the spec should be cleaned up to state
that the next method is the next element in the list of applicable
methods after the executing one, in both the argument and nonargument
cases.
jak
∂28-Dec-87 1129 Common-Lisp-Object-System-mailer with-accessors
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 28 Dec 87 11:29:49 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 311081; Mon 28-Dec-87 14:30:03 EST
Date: Mon, 28 Dec 87 14:29 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: with-accessors
To: common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: <871222181857.7.GREGOR@SPIFF.parc.xerox.com>
Message-ID: <19871228192947.3.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Tue, 22 Dec 87 18:18 PST
From: Gregor.pa@Xerox.COM
(with-accessors ((x position-x)
(y position-y))
p1
(setq x y))
I like this. I think we should put it in.
Is (with-accessors (x y)
p1
(setq x y))
allowed for consistency with with-slots? It would only work for classes
that use the naming convention that accessor function names are the same
as slot names, which might mean that its existence leads to confusion.
Hence I suggest that we should not allow this abbreviated syntax.
∂28-Dec-87 1204 Common-Lisp-Object-System-mailer Re: add-method when method exists
Received: from [128.81.41.234] by SAIL.STANFORD.EDU with TCP; 28 Dec 87 12:04:40 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by MEAD.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 123190; Mon 28-Dec-87 14:54:41 EST
Date: Mon, 28 Dec 87 14:53 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: add-method when method exists
To: Gregor.pa@XEROX.COM, kanderso@WILMA.BBN.COM
cc: common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: The message of 28 Dec 87 09:26 EST from kanderso@WILMA.BBN.COM
Message-ID: <19871228195358.4.MOON@EUPHRATES.SCRC.Symbolics.COM>
Line-fold: No
Summary of issues raised in this message:
1) Ambiguity in the documentation of add-method
2) General ambiguity in the language used in the spec
3) Should add-method become add-or-replace-method
4) Precisely when are errors signaled
5) Do we really want to make it an error to omit the primary method
Date: Mon, 28 Dec 87 09:26:37 -0500
From: kanderso@WILMA.BBN.COM
Date: Wed, 23 Dec 87 13:04 PST
From: Gregor.pa@XEROX.COM
In the current version of the spec, if add-method is used to add a
method to a generic function and there is already a method with the same
specializers and qualifiers an error is signaled....
Actually the language in the version of the spec that I have is
ambiguous, and may not mean what you said. It says (2-8) "If the given
method is already one of the methods on the generic function, as
determined by get-method, or if the method object is a method object of
another generic function, an error is signaled." It's unclear to me
whether the first use of "method", without "object" appended, means
that "the given method" is the method actually passed as an argument
to add-method, or means that "the given method" is any method with the
same generic function, qualifiers, and specializers. Whichever the
document means, it should say explicitly (1). It could be trying to say
that add-method signals an error if the method is already attached to
any generic function, or it could be saying not only that but in addition
add-method signals an error if the generic function already has a
method with the same qualifiers and specializers.
Almost everywhere in the document that the word "object" appears as a
suffix, it is probably a signal of this type of ambiguity. I think we
should eschew that phrasing if we can (2).
Effectively you're saying that add-method should become add-or-replace-method.
I have no objection to that change, and either name is okay with me. (3)
I don't want to first remove the old method because if I do,
the generic function will be in an illegal state (it will have no
primary method).
I agree that an error should not be signaled, but i don't see anything
wrong with calling REMOVE-METHOD.
Page 1-31 says an error is signaled if there is no primary method,
but it doesn't say -when- the error is signaled (4). Clearly the error can't
be signalled whenever there is a generic function in that state, since then
one could never create a new generic function. Since the spec speaks of
applicable methods, perhaps it means the error is signaled only when the
generic function is actually called, in which case you have no real problem.
However, we probably want CLOS systems to be able to report this error
early when they can detect it, so users don't have to wait until they test
their program on all possible cases to realize they have violated this
restriction. I think the spec is just extremely weak in this area, and
there isn't a simple fix, but I wanted to point it out, because depending
on how the spec is interpreted, the error you are worried about is not
actually signaled anyway.
I see nothing illegl about a
generic function without a primary method, and regularly define
protocols that have no primary methods just :AFTER methods.
You may be using Flavors or Common Loops. Flavors allows omitting the
primary method. I forget whether Common Loops does too. CLOS is
incompatible here. I forget why it's incompatible, but it's easy to
get around it by defining a primary method with no specialized parameters
that does nothing. (5)
∂28-Dec-87 1252 Common-Lisp-Object-System-mailer New Class Organization for CLOS Kernel
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 28 Dec 87 12:51:59 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 311191; Mon 28-Dec-87 15:52:11 EST
Date: Mon, 28 Dec 87 15:51 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: New Class Organization for CLOS Kernel
To: common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: <871223-143619-8688@Xerox>
Message-ID: <19871228205157.8.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: 23 Dec 87 14:34 PST
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
The following is my understanding of what we agreed to in Cambridge.
Agreed, except for some problems with the class relationships:
standard-accessor-method and standard-method should be disjoint for the
same reason that standard-class, built-in-class, and structure-class are
now disjoint. The principle underlying this is that we need to
distinguish between the class that is used by default by the various
macros, and the class from which other classes inherit. This allows a
programmer defining a new method to choose whether this method is to be
applicable to the default kind of object that the macros make or to all
objects (of the relevant general kind). For example, standard-class is
distinct from structure-class, and they both inherit from class, so that
a programmer can put a method on standard-class to affect classes made
by defclass, or on class to affect all classes. Probably this principle
should be in your list of principles.
It's okay for standard-class-slot-description to be a subclass of
standard-slot-description, provided the idea is that
standard-class-slot-description is a kludge to avoid putting the
:allocation into a slot. Otherwise there should be both
standard-class-slot-description and standard-instance-slot-description,
disjoint, and if we want we could also define a common superclass of
them. I don't have an opinion on which of those alternatives is
right since I don't yet understand exactly what you're trying to do
with slot-descriptions.
Forward-referenced-class should be disjoint from standard-class for the
same reason, except that forward-referenced-class should not exist at
all, in my opinion. It's okay for funcallable-standard-class to be a
subclass of standard-class if we really mean that
funcallable-standard-class is a specialization of the class you get with
defclass, not something distinct that wants to inherit some of the same
methods. I haven't seen a written description of funcallable-standard-class
yet, but my understanding is that that is the nature of it.
∂28-Dec-87 1316 Common-Lisp-Object-System-mailer with-accessors
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 28 Dec 87 13:16:42 PST
Received: from Semillon.ms by ArpaGateway.ms ; 28 DEC 87 12:41:47 PST
Date: Mon, 28 Dec 87 12:40 PST
From: Gregor.pa@Xerox.COM
Subject: with-accessors
To: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
cc: common-lisp-object-system@SAIL.STANFORD.EDU
Fcc: BD:>Gregor>mail>outgoing-mail-1.text
In-Reply-To: <19871228192947.3.MOON@EUPHRATES.SCRC.Symbolics.COM>
Message-ID: <871228124037.3.GREGOR@SPIFF.parc.xerox.com>
Line-fold: no
Date: Mon, 28 Dec 87 14:29 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Date: Tue, 22 Dec 87 18:18 PST
From: Gregor.pa@Xerox.COM
(with-accessors ((x position-x)
(y position-y))
p1
(setq x y))
I like this. I think we should put it in.
Is (with-accessors (x y)
p1
(setq x y))
allowed for consistency with with-slots? It would only work for classes
that use the naming convention that accessor function names are the same
as slot names, which might mean that its existence leads to confusion.
Hence I suggest that we should not allow this abbreviated syntax.
I agree that we should not allow this abbreviated syntax. I meant to
address that specifically in my message but I seem to have forgotten.
-------
∂28-Dec-87 1359 Common-Lisp-Object-System-mailer partial results of Cambridge meeting
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 28 Dec 87 13:59:19 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 311260; Mon 28-Dec-87 16:59:27 EST
Date: Mon, 28 Dec 87 16:59 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: partial results of Cambridge meeting
To: Common-Lisp-Object-System@SAIL.STANFORD.EDU
Message-ID: <19871228215909.9.MOON@EUPHRATES.SCRC.Symbolics.COM>
Here are some of my notes on things we decided at the meeting in
Cambridge earlier this month. I'm leaving out everything that is
specifically about meta objects, which was the bulk of the discussion.
This message is aimed just at finishing chapters 1 and 2. If there are
any disagreements, sing out. In cases where the documentation has
already been updated, I've noted that fact.
We decided to leave chapter 2 in its present format but add to its
introductory material a note that the present form of chapter 2 does not
attempt to address the division of a labor between what a generic
function does and what its standard methods do, and that that will be
changed in a later revision when meta-objects are finished. A few
things now in chapter 2 that really belong in chapter 3, such as the
descriptions of specific initialize-instance methods, will be moved.
We're all supposed to get in any final comments on chapters 1 and 2
as soon as possible, so that they can be mailed to the X3J13 committee
in January. I'll be sending mine in in a day or two.
For standard objects, EQL, EQUAL, and EQUALP are all the same as EQ.
Other equality functions treat standard objects the same as other
unrecognized objects, thus TREE-EQUAL uses EQL to compare standard
objects, and it is an error to use a standard object as an argument to
=, /=, CHAR-EQUAL, STRING-EQUAL, CHAR=, etc.
Add a :WRITER slot option and specify that
:ACCESSOR foo
is an abbreviation for
:READER foo :WRITER (SETF foo)
This is already in chapter 1 (1-11), but with some editing mistakes,
which I'll send separate mail about.
Change the syntax of WITH-SLOTS to be like MULTIPLE-VALUE-BIND, by
interchanging the instance form and the list of slot names. Do not
provide a way to have more than one instance form in a single
WITH-SLOTS.
SYMBOL-MACROLET definitely doesn't do anything special to the
macroexpansion environment, so a macro that's invoked in the body of a
SYMBOL-MACROLET (or WITH-SLOTS) cannot(emphasis!) tell whether a symbol
as a subform of an invocation of the macro is really a variable or is
going to get substituted. The remarks for SYMBOL-MACROLET thus recommend
that the forms should behave like variables, that is, reading should be
free of side-effects and evaluating either a read or a write multiple
times should be equivalent, except for speed, to doing it once. We
should supply examples of right and wrong ways to use SYMBOL-MACROLET.
For example,
(symbol-macrolet ((x (slot-value object 'x))) ...) ;good
(symbol-macrolet ((x (aref a (incf i)))) ...) ;bad, not idempotent
(symbol-macrolet ((x (aref a (1+ i)))) ...) ;good
(symbol-macrolet ((x (+ oldx offset))) ...) ;good, but read-only
(symbol-macrolet ((x (incf oldx offset))) ...) ;highly bad
(symbol-macrolet ((x (cons y z))) ...) ;bad, reading isn't idempotent
(symbol-macrolet ((x (caddr z))) ...) ;good
(symbol-macrolet ((x (throw 'tag))) ...) ;horrible
We don't have to use all these examples, I just quickly came up
with a bunch so there would be something to work from.
We discussed constructors for a while and I will send out a revised,
complete proposal in a couple days.
∂28-Dec-87 1851 Common-Lisp-Object-System-mailer Comments on Chapter 1
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 28 Dec 87 18:51:11 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 311406; Mon 28-Dec-87 21:51:28 EST
Date: Mon, 28 Dec 87 21:51 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Comments on Chapter 1
To: Common-Lisp-Object-System@SAIL.STANFORD.EDU
Message-ID: <19871229025115.7.MOON@EUPHRATES.SCRC.Symbolics.COM>
Comments on the draft of chapter 1 dated Dec 23, 1987 13:37. This is
probably my last round of comments for chapter 1.
1-10 and several others: I'm not sure that the introduction of the new term
"captured :initform form" really adds anything to understandability. It ends
up that "captured" is the only kind there is.
1-11 3rd paragraph last sentence: "Accessors are implemented using readers and
writers, and readers, writers, and accessors are implemented using {\bf
slot-value}." If there is such a thing as an accessor, it is either a reader
or writer, it isn't implemented using readers or writers. I'd rather see
"Reader and writer methods are implemented using {\bf slot-value}."
1-11 4th paragraph: several editing errors in switching between writer and
accessor here. I suggest "When a reader or writer is specified for a slot,
the name of the generic function to which the generated method belongs is
directly specified. If the name specified for the accessor option is the
symbol {\it name}, then the name of the generic function for reading the slot
is the symbol {\it name\/} and the name of the generic function for writing
the slot is the list {\tt (setf {\it name\/})}." Also the last sentence, "It
is possible to modify the behavior of these generic functions by writing
methods for them.", seems like a non-sequitur. The point this is trying to
make is that you can write methods explicitly with defmethod, as well as
writing methods implicitly with the slot options, and you can mix both kinds
of methods on the same generic function. Perhaps the sentence should be in
its own paragraph and should be rephrased slightly.
1-11 last paragraph: This is a good place to mention with-accessors,
assuming that we are adding it.
1-12: The second paragraph under "Inheritance of Slots and Slot Options"
no longer says what happens if the :allocation slot option is omitted.
It used to. Delaying that until later seems confusing to me.
1-13: "Reader and accessor methods are inherited in the sense described in
the section ``Inheritance of Methods.''" should say "writer" rather than
"accessor" now.
1-13 last paragraph: "If a given {\bf :default-initargs} class option
specifies an initialization argument of the same name more than once, the
leftmost supplies the value and the remaining occurrences are ignored."
I don't think this is right; it should be an error to specify the same
initialization argument name more than once in a single :default-initargs
class option.
1-14 last sentence: "there is also a method for {\tt setf} of {\tt S3} that
writes the value of {\tt S3}." This is wrong, it's a method for {\tt setf} of
{\tt C2-S3}. Perhaps the first half of the sentence should mention explicitly
that the reader method is on the generic function named C2-S3.
1-15 last paragraph in first section: In "discarding local slots that are not
defined in the new version of the instance", the last word is probably
supposed to be "class", not "instance", since "defined" refers to classes.
Alternatively, perhaps the word "defined" was supposed to be "accessible".
Also "and initializing newly-added shared slots" can't be part of the two-step
process of updating an instance. This phrase belongs two paragraphs earlier,
where we are discussing shared slots.
1-15 first paragraph in second section: "defined by old class" is missing
"the". Also this whole paragraph bothers me because it uses "defined" and
"specified" interchangeably, or else there is a subtle difference between the
two words that I haven't grasped. Earlier (1-12) "defined" meant only local
definitions of slots, as opposed to inherited ones, so a different word should
be used. "Accessible" if it fits, otherwise "specified" I guess.
1-16 first paragraph: "declass" should be "defclass". The meta object folks
could rightly point out that there is too much emphasis on defclass forms
here, that there are other ways to define classes, and that we could be
clearer about the distinction between the name layer and the object layer.
However, perhaps being pedantic about that would just make the writeup harder
to read for no real benefit.
With the above corrections I think the new description of class redefinition
is a definite improvement.
1-17: same specified/defined wording issue.
1-19 first sentence: Isn't the mapping from classes into types, rather than
the inverse as it says here? Not all types are mapped to a class.
1-20 in the table: "sequnce" should be "sequence".
1-20 bottom: The incomprehensible sentence "However, individual
implementations are not free to add subclass relationships involving
user-defined standard classes." was removed. I think what this meant to say
is that a standard class defined with no direct superclasses is guaranteed to
be disjoint with all of the classes in the table, except for t. That probably
needs to be said. Note: my little phrase "with no direct superclasses" there
seems like the cleanest way to rule out the loophole of the user explicitly
defining a subclass of one of the potentially built-in classes that doesn't
happen to be built-in.
1-20: Do we want to say in this document that we plan to add the following
types/classes to the table whenever Common Lisp is fixed to define their
relations to other types properly? It seems like that intention ought to
be documented someplace.
function hash-table package pathname random-state readtable stream
1-23 second paragraph: "The class {\tt apple} is a direct subclass of {\tt
fruit} and is rightmost in the precedence list." leads to an unfortunate
ambiguity where a reader might think that the direct subclass has to be the
very last element of the precedence list computed so far. A better way to say
it that avoids this ambiguity would be "The class {\tt apple} is a direct
subclass of {\tt fruit} and the class {\tt pie} is a direct subclass of
{\tt cinnamon}. Since {\tt apple} appears to the right of {\tt pie}
in the precedence list, {\tt fruit} goes next ..."
1-24 with-added-methods paragraph: In "If there is a lexically visible
ordinary function of the same name as one of the method definitions, that
function becomes the method function of the default method for the new generic
function of that name.", "as one of the method definitions" should be deleted,
or replaced by "as the specified generic function name."
1-27 rule 4: This could be misinterpreted as implying that if a method has
an &rest parameter, the value of that parameter will include the symbols
:allow-other-keys and t even if the arguments supplied by the caller of the
generic function did not include those symbols. We should say explicitly
that that is not the case; a method's &rest parameter will see only the
actual arguments. I think it would be clearer to go back to saying that
a method function receives keyword arguments in the same way that it would
if the method lambda-list had included &allow-other-keys.
1-31 second to last paragraph: "A method for {\bf compute-effective-method}
can be defined directly by using {\bf defmethod} or any of the other
method-defining forms..." is not really true. The other method-defining forms
can define a method for a generic function named compute-effective-method,
but it won't actually be the same generic function that the method combination
mechanism calls; that mechanism calls the generic function that has that name
globally, not any generic function that has that name lexically. I'd
let this refer only to defmethod and define-method-combination.
1-32 first paragraph: A period is missing in "procedure Some illustrative
examples".
1-34 first bullet: "those those"
1-34: How come "An error is signaled if {\bf call-next-method} is used in a
{\bf :before} or {\bf :after} method." was removed? I think we need to make
it clear that call-next-method isn't allowed in before and after methods.
1-34 last paragraph of first section: "shadowed" should be "shadow".
1-37 first bullet: I think "method-defining forms" here is a typo for
something else.
1-40 last paragraph of first section: "The \OS\ does not guarantee any given
order of evaluation of default value and {\bf :initform} forms." is ambiguous.
This could be interpreted as saying that CLOS doesn't guarantee that all the
default value forms are evaluated before any of the :initform forms. But I
think it does guarantee that. What we really mean to say here is that CLOS
doesn't guarantee which of two default value forms is evaluated first, and
furthermore CLOS doesn't guarantee which of two :initform forms is evaluated
first. Perhaps it could be better said as two sentences.
1-41 fourth bullet: "If a given {\bf :default-initargs} class option specifies
an initialization argument of the same name more than once, the leftmost
supplies the value and the remaining occurrences are ignored." should be
deleted and replaced by: "If a given {\bf :default-initargs} class option
specifies two initialization arguments that initialize the same slot, the
leftmost supplies the value and the values of the remaining default value
forms are ignored."
∂28-Dec-87 1947 Common-Lisp-Object-System-mailer Standardizing the macroexpansion of make-method-call
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 28 Dec 87 19:47:00 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 311434; Mon 28-Dec-87 22:47:16 EST
Date: Mon, 28 Dec 87 22:47 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Standardizing the macroexpansion of make-method-call
To: Common-Lisp-Object-System@SAIL.STANFORD.EDU
Message-ID: <19871229034700.8.MOON@EUPHRATES.SCRC.Symbolics.COM>
Gregor pointed out that in order to be able to analyze effective method
forms, which is something we claim can be done, it is necessary to be
able to recognize the macroexpansion of MAKE-METHOD-CALL. This is true.
This message is a fairly long discussion of the issues. You needn't
include all of it in replies.
I see three possible approaches:
(1) Leave MAKE-METHOD-CALL the way it is and add a new function
METHOD-CALL-P. Given a form this returns the method it calls, or NIL if
the form is not an invocation of a method. METHOD-CALL-P returns a
second value which is an ordered list of the methods reachable by
CALL-NEXT-METHOD when this method is called. If the first value is NIL
the second value is also NIL.
(2) Add a macro METHOD-CALL, which only expands correctly in the same
special environment that MAKE-METHOD-CALL is documented to depend on.
Define MAKE-METHOD-CALL to expand into METHOD-CALL. The syntax of
METHOD-CALL is (METHOD-CALL method [:NEXT-METHODS (next-method*)]), i.e.
if the :NEXT-METHODS option is present, it is a possibly empty ordered
list of methods reachable by CALL-NEXT-METHOD. If the :NEXT-METHODS
option is absent, CALL-NEXT-METHOD is not available in the method.
(3) Add a macro METHOD-CALL, which only expands correctly in the same
special environment that MAKE-METHOD-CALL is documented to depend on.
Get rid of MAKE-METHOD-CALL and require writers of method combination
procedures to generate METHOD-CALL forms directly.
The advantage of approach 1 is that the structure of a method invocation
form is completely up to the implementation. Also, the interpretation
of an effective method form does not have to be dependent on an
environment. By the way, this is what Flavors does, thus this is a
use-tested approach.
The advantage of approaches 2 and 3 is that MAKE-METHOD-CALL's special
dynamic environment could be eliminated, in favor of wrapping a MACROLET
of METHOD-CALL to an implementation-dependent definition around the
effective method form, when actually compiling it.
The advantage of approach 3 is that it leaves CLOS the simplest.
The disadvantage of approach 3 is that MAKE-METHOD-CALL provides a bunch
of convenience features that would now have to be done by hand. Approach
2 solves this at the cost of some evident redundancy.
None of this deals with the fact that a thing reachable by CALL-NEXT-METHOD
can be not only a regular method, but a grouping of before, primary, and
after methods; currently this works by MAKE-METHOD-CALL accepting forms in
place of methods and somehow translating them. In Flavors no formal method
is required for this, but it sounds like CLOS is going to need an actual
method object of some new class? Or can we get away with just returning a
form as an element of the second value of METHOD-CALL-P (approach 1) or
including a form as an element of the :NEXT-METHODS option (approaches 2&3)?
We need to figure out the answers to those questions before we can proceed.
Flavors used to use something like approach 3, and switched to approach 1
to speed up method combination. I haven't been able to reconstruct the
full details of what happened (it was years ago), but if the efficiency
concern there was not relevant to CLOS, I would prefer approach 2. To
judge your opinion on approach 3, here are the examples from 2-34 through
2-36 rewritten in approach 3; consult your hardcopy for the originals.
This is assuming we can just put a form where a method object belongs.
;;; Examples of the short form of define-method-combination
(define-method-combination and :identity-with-one-argument t)
(defmethod func and ((x class1) y) ...)
;;; The equivalent of this example in the long form is:
(define-method-combination and
(&optional (order ':most-specific-first))
((around (:around))
(primary (and) :order order :required t))
(if around
`(method-call ,(first around)
:next-methods
`(,@(rest around)
,(if (rest primary)
`(and ,@(mapcar #'(lambda (p)
`(method-call ,p))
primary))
(first primary))))
(if (rest primary)
`(and ,@(mapcar #'(lambda (p)
`(method-call ,p))
primary))
(method-call ,(first primary)))))
;;; Examples of the long form of define-method-combination
;The default method-combination technique
(define-method-combination standard ()
((around (:around))
(before (:before))
(primary () :required t)
(after (:after)))
(if around
`(method-call ,(first around)
:next-methods
`(,@(rest around)
(multiple-value-prog1
(progn
,@(mapcar #'(lambda (b)
`(method-call ,b))
before)
,(if (rest primary)
`(and ,@(mapcar #'(lambda (p)
`(method-call ,p))
primary))
(first primary)))
,@(mapcar #'(lambda (a)
`(method-call ,a))
(reverse after)))))
`(multiple-value-prog1
(progn
,@(mapcar #'(lambda (b)
`(method-call ,b))
before)
,(if (rest primary)
`(and ,@(mapcar #'(lambda (p)
`(method-call ,p))
primary))
(first primary)))
,@(mapcar #'(lambda (a)
`(method-call ,a))
(reverse after)))))
[several examples skipped]
;Order methods by positive integer qualifiers
;:around methods are disallowed to keep the example small
(define-method-combination example-method-combination ()
((methods positive-integer-qualifier-p))
`(progn ,@(mapcar #'(lambda (m) `(method-call ,m))
(stable-sort methods #'<
:key #'(lambda (method)
(first (method-qualifiers
method)))))))
(defun positive-integer-qualifier-p (method-qualifiers)
(and (= (list-length method-qualifiers) 1)
(typep (first method-qualifiers) '(integer 0 *))))
∂29-Dec-87 1435 Common-Lisp-Object-System-mailer Method Combination Objects
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 29 Dec 87 14:35:19 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 311848; Tue 29-Dec-87 17:27:38 EST
Date: Tue, 29 Dec 87 17:27 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Method Combination Objects
To: Common-Lisp-Object-System@SAIL.STANFORD.EDU
Supersedes: <19871229180330.0.MOON@EUPHRATES.SCRC.Symbolics.COM>
Comments: I forgot to include the describe-method-concisely generic function.
Message-ID: <19871229222722.4.MOON@EUPHRATES.SCRC.Symbolics.COM>
At the Cambridge meeting I promised to mail this out.
Currently method combination types are represented in a kludgey fashion,
as a pair of objects: a symbol that names the type, and a list of options.
It would be better to do this in an object-oriented way, the same as
everything else. Here is a proposal for how it would look. Method
combination objects are meta objects, so this is all chapter 3 material.
There are a couple of minor modifications to chapters 1 and 2, which I
will note at the end.
Method Combination Naming Layer
This layer is concerned with mapping method combination type names, as
seen in the :method-combination option to defgeneric, to method
combination objects.
(method-combination-maker name) => function
This function maps the name of a method combination type into a function
that accepts the options seen in the :method-combination option to
defgeneric and returns the method combination object.
method-combination-maker signals an error if -name- is unrecognized.
-function- should signal an error if the options are unrecognized.
(apply (method-combination-maker name) options) is how a method combination
name and options are converted into an object.
(setf (method-combination-maker name) function) is how a method combination
type is defined.
(setf (method-combination-maker name) nil) is how a method combination
type is undefined. (Or we could have a separate function for this.)
(method-combination-name method-combination) => symbol
(method-combination-options method-combination) => list
These two generic functions perform the inverse mapping.
Why we have method-combination-maker instead of just using make-instance:
- The names of method combination types that we have chosen are not
appropriate as names of classes. These names were chosen on the
assumption that they would be in their own namespace. Thus either we
have to have a new function to map from the method combination name
to the class object, or we have to change all the names. Changing
all the names would make the programmer interface awkward.
- The options seen in the :method-combination option to defgeneric
are defined by a lambda-list in define-method-combination, rather
than being just keyword arguments. Hence it makes sense to receive
these options with a function. We could change these options into
keywords suitable for use as initialization arguments, but this might
make the programmer interface awkward. If we just passed the whole
list of options as one :options initialization argument, we wouldn't
be exploiting any Lisp mechanism to parse the options.
- Several method combination types might share a single class.
- A single method combination type name might map into several different
classes, depending on the options.
- A function returned by method-combination-maker might return the same
object each time it is called, instead of making a new object.
For these reasons it seems better to interpose an extra layer between
make-instance and the name and options of a method combination type.
Method Combination Object Layer
method-combination
This class is a superclass of all classes of method combination.
standard-method-combination
This class is the class of the method combination object used by default
when :method-combination is not specified.
Other implementation-dependent subclasses of method-combination exist.
For example, all invocations of the short form of
define-method-combination probably use one class, and each invocation of
the long form of define-method-combination probably defines a new class
which has a superclass in common with standard-method-combination.
CLOS does not specify how many of these classes there are nor what
their names are.
(compute-effective-method generic-function method-list method-combination)
=> effective-method-form
This generic function performs part 3 of the determination of the
effective method. define-method-combination works through methods that
specialize the third parameter.
(describe-method-concisely generic-function method method-combination)
This generic function prints a description of the method onto
*standard-output*. The value returned is ignored.
define-method-combination defines a method for describe-method-concisely
that uses the :description option of the long form to control
what it prints.
Other generic functions specialized by method combinations are not
currently defined by CLOS, but program development environments are
likely to have some.
A generic function object records a method combination object, rather
than the name and options of a method combination type. This changes
the initialization arguments and structural access functions for
generic functions from what is in chapter 3 now. defgeneric calls
method-combination-maker before it calls ensure-generic-function.
Example
The short form of define-method-combination could have been defined
as follows:
(defclass short-form-method-combination
(method-combination)
((name :initarg name :reader method-combination-name)
(order :initarg order)
(documentation :initarg documentation :reader documentation)
(operator :initarg operator)
(identity-with-one-argument :initarg identity-with-one-argument)))
(defmethod method-combination-options ((mc short-form-method-combination))
(list (slot-value mc 'order)))
(defmethod compute-effective-method (generic-function
methods
(mc short-form-method-combination))
(let ((primary-methods (remove (list (slot-value mc 'name))
methods :key #'method-qualifier
:test-not #'equal))
(around-methods (remove '(:around)
methods :key #'method-qualifier
:test-not #'equal)))
(when (eq (slot-value mc 'order) ':most-specific-last)
(setq primary-methods (reverse primary-methods)))
(dolist (method (set-difference methods
(union primary-methods around-methods)))
(invalid-method-error method "The qualifiers of ~S, ~:S, are not ~S or ~S"
method (method-qualifiers method)
(list (slot-value mc 'name)) '(:around)))
(make-method-call `(,@around-methods
,(make-method-call primary-methods
:operator (slot-value mc 'operator)
:identity-with-one-argument
(slot-value mc 'identity-with-one-argument)))
:operator :call-next-method)))
(defmethod describe-method-concisely
(generic-function
method
(method-combination short-form-method-combination))
(declare (ignore generic-function))
(write-string (string-downcase (string (first (method-qualifiers method))))))
(defmacro define-method-combination
(name &key (documentation nil)
(operator name)
(identity-with-one-argument nil))
`(setf (method-combination-maker ',name)
#'(lambda (&optional (order ':most-specific-first))
(make-instance 'short-form-method-combination
'name ',name
'order order
'documentation ',documentation
'operator ',operator
'identity-with-one-argument ',identity-with-one-argument))))
Example of Defining a Method Combination Type via Inheritance
;This example defines a method combination type that is similar
;to standard method combination, except that it also allows :or
;methods. The :or methods are executed after the :before methods,
;before the :after methods, inside the :around methods, and before
;the primary method. The primary method is only called if all the
;:or methods return nil; if any :or method returns non-nil, its
;value becomes the value of the generic function (or the value
;returned by call-next-method in the least specific :around method)
;in place of the values of the most specific primary method.
;This assumes approach 2 or 3 to making effective method code
;analyzable, and assumes one particular code analysis tool, whose
;details I will not try to explain here.
;Those assumptions are not critical.
;I'm assuming we don't want to try to extend the define-method-combination
;macro so that it could exploit inheritance. Instead I will
;define the example directly in terms of the next layer down.
(defclass standard-method-combination-with-or
(standard-method-combination)
())
(setf (method-combination-maker 'standard-with-or)
#'(lambda () (make-instance 'standard-method-combination-with-or)))
;This uses call-next-method to get the effective method in the absence
;of any :or methods, then it modifies the effective method form to
;incorporate the :or methods in an OR special form wrapped around the
;call to the most specific primary method.
(defmethod compute-effective-method (generic-function
methods
(mc standard-method-combination-with-or))
(let ((or-methods (remove '(:or) methods :key #'method-qualifiers
:test-not #'equal))
(other-methods (remove '(:or) methods :key #'method-qualifiers
:test #'equal)))
(lt:copyforms #'(lambda (subform kind usage)
(declare (ignore usage))
(if (and (listp kind) (listp subform)
(eq (first subform) 'method-call)
(null (method-qualifiers (second subform))))
;; Put or methods before primary method
(values `(or ,@(mapcar #'(lambda (method)
`(method-call ,method))
or-methods)
,subform)
t)
;; Leave all other subforms of effective method alone
subform))
(call-next-method generic-function other-methods mc))))
Modifications to Chapters 1 and 2
1-31: The arguments to compute-effective-method have been changed.
2-43: The value of the :method-combination argument to
ensure-generic-function becomes a method combination object. Currently,
the value of this argument isn't really documented at all.
∂29-Dec-87 1435 Common-Lisp-Object-System-mailer Method Combination Objects
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 29 Dec 87 14:35:23 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 311658; Tue 29-Dec-87 13:03:40 EST
Date: Tue, 29 Dec 87 13:03 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Method Combination Objects
To: Common-Lisp-Object-System@SAIL.STANFORD.EDU
Message-ID: <19871229180330.0.MOON@EUPHRATES.SCRC.Symbolics.COM>
At the Cambridge meeting I promised to mail this out.
Currently method combination types are represented in a kludgey fashion,
as a pair of objects: a symbol that names the type, and a list of options.
It would be better to do this in an object-oriented way, the same as
everything else. Here is a proposal for how it would look. Method
combination objects are meta objects, so this is all chapter 3 material.
There are a couple of minor modifications to chapters 1 and 2, which I
will note at the end.
Method Combination Naming Layer
This layer is concerned with mapping method combination type names, as
seen in the :method-combination option to defgeneric, to method
combination objects.
(method-combination-maker name) => function
This function maps the name of a method combination type into a function
that accepts the options seen in the :method-combination option to
defgeneric and returns the method combination object.
method-combination-maker signals an error if -name- is unrecognized.
-function- should signal an error if the options are unrecognized.
(apply (method-combination-maker name) options) is how a method combination
name and options are converted into an object.
(setf (method-combination-maker name) function) is how a method combination
type is defined.
(setf (method-combination-maker name) nil) is how a method combination
type is undefined. (Or we could have a separate function for this.)
(method-combination-name method-combination) => symbol
(method-combination-options method-combination) => list
These two generic functions perform the inverse mapping.
Why we have method-combination-maker instead of just using make-instance:
- The names of method combination types that we have chosen are not
appropriate as names of classes. These names were chosen on the
assumption that they would be in their own namespace. Thus either we
have to have a new function to map from the method combination name
to the class object, or we have to change all the names. Changing
all the names would make the programmer interface awkward.
- The options seen in the :method-combination option to defgeneric
are defined by a lambda-list in define-method-combination, rather
than being just keyword arguments. Hence it makes sense to receive
these options with a function. We could change these options into
keywords suitable for use as initialization arguments, but this might
make the programmer interface awkward. If we just passed the whole
list of options as one :options initialization argument, we wouldn't
be exploiting any Lisp mechanism to parse the options.
- Several method combination types might share a single class.
- A single method combination type name might map into several different
classes, depending on the options.
- A function returned by method-combination-maker might return the same
object each time it is called, instead of making a new object.
For these reasons it seems better to interpose an extra layer between
make-instance and the name and options of a method combination type.
Method Combination Object Layer
method-combination
This class is a superclass of all classes of method combination.
standard-method-combination
This class is the class of the method combination object used by default
when :method-combination is not specified.
Other implementation-dependent subclasses of method-combination exist.
For example, all invocations of the short form of
define-method-combination probably use one class, and each invocation of
the long form of define-method-combination probably defines a new class
which has a superclass in common with standard-method-combination.
CLOS does not specify how many of these classes there are nor what
their names are.
(compute-effective-method generic-function method-list method-combination)
=> effective-method-form
This generic function performs part 3 of the determination of the
effective method. define-method-combination works through methods that
specialize the third parameter.
Other generic functions specialized by method combinations are not
currently defined by CLOS, but program development environments are
likely to have some.
A generic function object records a method combination object, rather
than the name and options of a method combination type. This changes
the initialization arguments and structural access functions for
generic functions from what is in chapter 3 now. defgeneric calls
method-combination-maker before it calls ensure-generic-function.
Example
The short form of define-method-combination could have been defined
as follows:
(defclass short-form-method-combination
(method-combination)
((name :initarg name :reader method-combination-name)
(order :initarg order)
(documentation :initarg documentation :reader documentation)
(operator :initarg operator)
(identity-with-one-argument :initarg identity-with-one-argument)))
(defmethod method-combination-options ((mc short-form-method-combination))
(list (slot-value mc 'order)))
(defmethod compute-effective-method (generic-function
methods
(mc short-form-method-combination))
(let ((primary-methods (remove (list (slot-value mc 'name))
methods :key #'method-qualifier
:test-not #'equal))
(around-methods (remove '(:around)
methods :key #'method-qualifier
:test-not #'equal)))
(when (eq (slot-value mc 'order) ':most-specific-last)
(setq primary-methods (reverse primary-methods)))
(dolist (method (set-difference methods
(union primary-methods around-methods)))
(invalid-method-error method "The qualifiers of ~S, ~:S, are not ~S or ~S"
method (method-qualifiers method)
(list (slot-value mc 'name)) '(:around)))
(make-method-call `(,@around-methods
,(make-method-call primary-methods
:operator (slot-value mc 'operator)
:identity-with-one-argument
(slot-value mc 'identity-with-one-argument)))
:operator :call-next-method)))
(defmacro define-method-combination
(name &key (documentation nil)
(operator name)
(identity-with-one-argument nil))
`(setf (method-combination-maker ',name)
#'(lambda (&optional (order ':most-specific-first))
(make-instance 'short-form-method-combination
'name ',name
'order order
'documentation ',documentation
'operator ',operator
'identity-with-one-argument ',identity-with-one-argument))))
Example of Defining a Method Combination Type via Inheritance
;This example defines a method combination type that is similar
;to standard method combination, except that it also allows :or
;methods. The :or methods are executed after the :before methods,
;before the :after methods, inside the :around methods, and before
;the primary method. The primary method is only called if all the
;:or methods return nil; if any :or method returns non-nil, its
;value becomes the value of the generic function (or the value
;returned by call-next-method in the least specific :around method)
;in place of the values of the most specific primary method.
;This assumes approach 2 or 3 to making effective method code
;analyzable, and assumes one particular code analysis tool, whose
;details I will not try to explain here.
;Those assumptions are not critical.
;I'm assuming we don't want to try to extend the define-method-combination
;macro so that it could exploit inheritance. Instead I will
;define the example directly in terms of the next layer down.
(defclass standard-method-combination-with-or
(standard-method-combination)
())
(setf (method-combination-maker 'standard-with-or)
#'(lambda () (make-instance 'standard-method-combination-with-or)))
;This uses call-next-method to get the effective method in the absence
;of any :or methods, then it modifies the effective method form to
;incorporate the :or methods in an OR special form wrapped around the
;call to the most specific primary method.
(defmethod compute-effective-method (generic-function
methods
(mc standard-method-combination-with-or))
(let ((or-methods (remove '(:or) methods :key #'method-qualifiers
:test-not #'equal))
(other-methods (remove '(:or) methods :key #'method-qualifiers
:test #'equal)))
(lt:copyforms #'(lambda (subform kind usage)
(declare (ignore usage))
(if (and (listp kind) (listp subform)
(eq (first subform) 'method-call)
(null (method-qualifiers (second subform))))
;; Put or methods before primary method
(values `(or ,@(mapcar #'(lambda (method)
`(method-call ,method))
or-methods)
,subform)
t)
;; Leave all other subforms of effective method alone
subform))
(call-next-method generic-function other-methods mc))))
Modifications to Chapters 1 and 2
1-31: The arguments to compute-effective-method have been changed.
2-43: The value of the :method-combination argument to
ensure-generic-function becomes a method combination object. Currently,
the value of this argument isn't really documented at all.
∂30-Dec-87 0924 Common-Lisp-Object-System-mailer Comments on Chapter 2
Received: from [128.81.41.234] by SAIL.STANFORD.EDU with TCP; 30 Dec 87 09:23:53 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by MEAD.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 123561; Tue 29-Dec-87 20:09:18 EST
Date: Tue, 29 Dec 87 20:08 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Comments on Chapter 2
To: Common-Lisp-Object-System@SAIL.STANFORD.EDU
Message-ID: <19871230010835.1.MOON@EUPHRATES.SCRC.Symbolics.COM>
Comments on Chapter 2, draft dated Nov 11 1987 15:57 (when I checked
yesterday, this was still the most recent on SAIL). This is a mixture
of editorial comments and several comments on the substance of the
specification. I apologize for not having time to separate them.
2-3: It looks like this is the place for the disclaimer that says the
current version of chapter 2 doesn't try to be careful about the division
of labor between the generic functions it describes and their methods,
and that this will be revisited and revised when chapter 3 is finished.
2-3: The method signature example has &opt where it should have
&optional. The description implies that M is the name of a method,
whatever that is, but examination of method signatures in the text shows
that M is really the name of a generic function. Also in all the method
signatures, the text in brackets naming the kind of method should be
flush right.
2-5: cboundp, class-name, cmakunbound, and symbol-class aren't really
general Common Lisp support tools. I would move them to the "functions
underlying" table.
2-6: I find this notation inordinately confusing, but I don't have any
suggestions for improving it. I could suggest getting rid of the
extensions and using only standard BNF. That would mean that we would
not be able to specify in the BNF syntax restrictions that an item can
appear only once; that would have to be left to the text. If people
feel that editorially it's worth having that information in the BNF and
that therefore we need this idiosyncratic notation, I can live with it.
2-8 add-method arguments: I don't understand the reference to a generic
function not having a lambda-list. How is that possible?
2-9 call-next-method second dash bullet: "and there is no applicable
primary method" should be "and there are no more primary methods" or
words to that effect. Actually I'm not sure if these bullets are really
needed here, or if it would be better to leave all that stuff up to
chapter 1.
2-11 cboundp arguments: I'm not sure what "the null environment" this
refers to is. Since chapter 2 isn't really trying to explain how these
environments work (I assume we're going to do that in chapter 3?) maybe
it would be best not to say anything more than the analogy to &environment
in macros.
2-12 change-class arguments last sentence: (symbol-class symbol) should
be (symbol-class new-class) since the method signature uses new-class
as the parameter name.
2-15 class-changed: Since users can write methods for this, and this is
not a meta object generic function, we can't get away here with
obscuring the division of labor between the generic function and its
methods. This is explained pretty well in chapter 1 now, so the
explanation of what the standard primary method can be relied upon by
other methods to do can be lifted from there.
2-15 class-changed purpose: "evalued" should be "evaluated".
2-18 class-of purpose and values: There is a terminology problem here.
An object is an instance of only one class, we can't speak of the most
specific class of which the object is an instance. The terminology I
prefer is that an object "is a member" of the class of which it "is
an instance" and also "is a member" of each superclass of that class.
This comes from the use of "member" with types. I don't think chapter 1
has introduced that term, however; perhaps it ought to. The easiest
way to fix the writeup of class-of is simply to say "The function
class-of returns the class of which the given object is an instance."
It's for reasons like this that we need a glossary. Is the glossary
file on SAIL up to date? We should include it in the X3J13 88-002
document.
2-19 cmakunbound: see comment on 2-11
2-21 defclass syntax: generic-function-name is a bit trickier once
:writer is added here. For :reader and :accessor generic-function-name
is a symbol, but for :writer it's either a symbol or a list (setf symbol).
I suggest calling the argument to :reader and :accessor reader-function-name
and calling the argument to :writer writer-function-name. The next page
contains italicized words with no obvious referent other than this syntax
table, so don't forget to keep the next page consistent with any changed names.
2-23 defclass :initarg slot option: This paragraph refers twice to a
":initform argument". I think this is a typo for ":initform slot option."
2-23 defclass :initform and :default-initargs: The dynamic environment of
evaluation is the same for both of these, but the wording of the description
differs. I like the wording used with :default-initargs better and I suggest
that :initform be changed.
2-23 defclass :default-initargs option: An initialization argument name isn't
allowed to appear more than once in a single :default-initargs option, delete
the reference to that (second to last sentence).
2-24, 1-15: 2-24 defines exactly when defclass redefines a class, in
terms of the "proper name" concept. 1-15 is vague on this. We should
make sure the two chapters agree. What 2-24 says is what we want,
right? Editorial comment: the wording on 2-24 isn't so hot, because it's
a run-on sentence and because the word "class" appears enough times to
make my head spin.
2-24: With the introduction of :writer, occurrences of "accessor" on this
page should probably be "writer", since :accessor is now understood as
an abbreviation for :reader plus :writer.
2-26: I don't understand why method-specifier is a separate nonterminal.
With method-description, -specifier, and -qualifier, things get confusing.
Why not make method-description include the complete syntax directly?
method-specifier isn't referenced anywhere else.
2-27 last line: "proclain proclamation" should be "declaration
proclamation", "declaration" in boldface.
2-29 first line: This says that removing a :method from a defgeneric and
re-evaluating the defgeneric does not remove the old method. While that's
a good default behavior, we should make sure not to rule out smart program
development environments that know better what is going on and remove the
old method in cases where the user thinks that's appropriate. In the Error
Terminology introduced in chapter 1, implementations should be free to
extend this. Redefinition is a program development environment issue, not
really a language issue, anyway.
2-30 define-method-combination syntax: I guess this should be using that
double-bracket notation I said I didn't like for short-form-option and
for long-form-option. None of the options is allowed to appear multiple
times.
2-33 last line: Delete the word "argument", it's confusing to call the
doc-string an argument.
2-35, 2-36: The examples headed ";A simple way to try several methods
until one returns non-nil" are actually examples of trying several methods
until one returns nil. In addition, it's confusing that these are 'and'
method combination just like the examples on 2-34. "and" should be changed
to "or" throughout the four examples on pp. 2-35 and 2-36.
2-36 last example: It's probably better style to use length rather than
list-length.
2-37 defmethod purpose: Starting off the purpose discussion with lambda-list
congruence seems odd. Perhaps that paragraph should be moved to Remarks.
2-38 defmethod second remarks paragraph: This implies that equality of
parameter specializers is defined by the Lisp EQUAL function, but that
can't really be true. In an EQL parameter specializer, the objects are
compared with EQL, not EQUAL. There is no Lisp function that directly
implements the test for equality of parameter specializers. Of course
the function is very easy to write. I would just delete "(equal)" here.
2-40 describe purpose and method signatures: Requiring a method for the
class t is wrong. What CLOS actually requires is that for any object
that exists, there is always an applicable method. The language of
method signatures doesn't provide any way to say this, so I think we
should simply say that there is a standard-object method, and there are
enough other methods to ensure that there is always an applicable
method. Note that if there were a method on the class t, it would not
be able to describe anything about its argument, unless it started with
a type dispatch, since it could not know anything about the type of the
argument.
2-42 second bullet: Implementations should be allowed to extend the
set of symbols acceptable as the second argument to documentation, in
line with the error terminology outlined in chapter 1.
2-43 ensure-generic-function second arguments paragraph: "and and"
2-45 generic-flet syntax: In the list of suggested changes he handed
out two years ago, Guy Steele suggested allowing declarations before
the body of flet, labels, and macrolet. The cleanup committee doesn't
seem to have picked up on this (I checked the latest issue status list
I had, which is only a month old). If FLET and LABELS change, of course
GENERIC-FLET and GENERIC-LABELS should change too, so we need to stay
on top of this. If I get a chance I'll send a cleanup reminder.
2-46, 2-47, 2-49: See comment on 2-26.
2-47 generic-function syntax: This takes the same restricted lambda-list
as defgeneric, generic-flet, etc. so the syntax for that should be
copied here. Alternatively the cross-reference under Arguments could
be updated, but that isn't the style in which generic-flet was done.
2-49 generic-labels syntax: See comment on 2-45.
2-51 get-method remarks: See comment on 2-38. Qualifiers are compared
with EQUAL, but specializers have to be compared a different way.
2-52, 2-53, 2-54 initialize-instance: The stuff about
initialize-instance methods on various meta object classes should be
moved into chapter 3. Also it contains some errors, for instance the
methods are :after methods, not primary methods, I'm fairly sure.
2-54 initialize-instance values: I think the value should be a don't
care, since that's what 1-43 implies. Why run the risk of someone
writing a method that returns the wrong value?
2-56 invalid-method-error: This function should not be generic. It
was not generic in the last version I reviewed; I don't know how
genericness accidentally crept in. Once the genericness and method
signature are removed, the rest of the writeup is okay.
2-57 make-instance: The method signatures for standard-method and
standard-generic-function are mistakes and should be removed. The stuff
about making instances of these classes in the remarks section should
be moved to chapter 3. By the way, I believe that the initialization
arguments for a class should be documented with the class, rather than
lumping all classes together under initialize-instance and make-instance.
Right now chapter 2 doesn't document any classes, but certainly chapter
3 will include pages for several classes.
2-58 make-instance first remarks paragraph: boring.
2-59 make-instances-obsolete second purpose paragraph: Cross out
"newly-redefined"; it might not be if the user called the function
explicitly. In the last sentence, change "may" to "will"; once
make-instances-obsolete has been called, it is guaranteed that
update-instance-structure will be called on each instance some
time before the next time a slot value of that instance is accessed.
2-59 make-instances-obsolete second arguments paragraph: Cross out
"symbol and".
2-65 no-applicable-method: I'm not sure that the default method should
be on standard-generic-function, rather than generic-function or t.
Why would we want the default method to be on a more specialized class?
2-66 print-object: See comment on 2-40.
2-68 remove-method method signatures: I don't think the second parameter
should be specialized. I think there are a few other generic functions
in here whose method signatures are overzealously specialized. Only
chapter 3 knows for sure, of course, but it seems to me that most of
these should accept any value for arguments other than the main
specialized one.
2-72 slot-missing method signatures: As on 2-65, shouldn't the default
method be on a less specialized class?
2-73 slot-unbound method signatures: see comment on 2-72
2-74 slot-value second remarks paragraph: The fourth argument to
slot-missing in this case is the symbol setf, not the list
(setf slot-value).
2-75 symbol-class last arguments paragraph: see comment on 2-11
2-76 symbol-macrolet second remarks paragraph: clarify that
symbol-macrolet can be shadowed by let. In other words, symbol-macrolet
only substitutes for occurrences of -symbol- that would be in the scope
of a lexical binding of -symbol- surrounding the body. Also
symbol-macrolet does not substitute for occurrences of a -symbol-
inside an -expansion-. Illustrative examples:
(symbol-macrolet ((x 'foo))
(list x (let ((x 'bar)) x))) => (foo bar), not (foo foo)
and ==> (list 'foo (let ((x 'bar)) x)), not
(let 'foo (let (('foo 'bar)) 'foo)).
(symbol-macrolet ((x (1+ x)))
(print x)) ==> (print (1+ x)), not (print (1+ (1+ (1+ ....
2-77 update-instance-structure second purpose paragraph: Since users can
write methods for this, and this is not a meta object generic function,
we can't get away here with obscuring the division of labor between the
generic function and its methods. This is explained pretty well in
chapter 1 now, so the explanation of what the standard primary method
can be relied upon by other methods to do can be lifted from there.
Also change "evalued" to "evaluated".
2-77 update-instance-structure: change "deleted-slots" to "discarded-slots"
to be consistent with 1-16. Slots that used to be local but are now
shared are included in the discarded-slots.
2-78 update-instance-structure example: In two places in the first
defmethod, "new" should be "pos". Also the comment was erroneously
copied from a class-changed example and a new comment is needed
saying something like transform the coordinates to polar and store
into the new slots. Use of with-slots in the example needs to be
updated to the new with-slots syntax. Also the indentation could
be standardized, some things are indented one space where the style
used everywhere else would have them indented two spaces.
2-80: See comment on 2-26
∂04-Jan-88 1510 Common-Lisp-Object-System-mailer Re: with-accessors
Received: from RELAY.CS.NET by SAIL.STANFORD.EDU with TCP; 4 Jan 88 15:10:47 PST
Received: from relay2.cs.net by RELAY.CS.NET id af01627; 4 Jan 88 17:31 EST
Received: from csc.ti.com by RELAY.CS.NET id ax08411; 4 Jan 88 17:14 EST
Received: from Jenner by tilde id AA01592; Mon, 4 Jan 88 15:39:32 CST
Message-Id: <2777319424-9830357@Jenner>
Date: Mon, 4 Jan 88 15:37:04 CST
From: Patrick H Dussud <DUSSUD%jenner.csc.ti.com@RELAY.CS.NET>
To: common-lisp-object-system@SAIL.STANFORD.EDU
Subject: Re: with-accessors
In-Reply-To: Msg of Mon, 28 Dec 87 12:40 PST from Gregor.pa@xerox.com
Date: Mon, 28 Dec 87 12:40 PST
From: Gregor.pa@xerox.com
Subject: with-accessors
Date: Mon, 28 Dec 87 14:29 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Date: Tue, 22 Dec 87 18:18 PST
From: Gregor.pa@Xerox.COM
(with-accessors ((x position-x)
(y position-y))
p1
(setq x y))
I like this. I think we should put it in.
Is (with-accessors (x y)
p1
(setq x y))
allowed for consistency with with-slots? It would only work for classes
that use the naming convention that accessor function names are the same
as slot names, which might mean that its existence leads to confusion.
Hence I suggest that we should not allow this abbreviated syntax.
I agree that we should not allow this abbreviated syntax. I meant to
address that specifically in my message but I seem to have forgotten.
-------
That sounds good.
Patrick.
∂05-Jan-88 1243 Common-Lisp-Object-System-mailer New Class Organization for CLOS Kernel
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 5 Jan 88 12:43:32 PST
Received: from Semillon.ms by ArpaGateway.ms ; 05 JAN 88 12:43:46 PST
Date: Tue, 5 Jan 88 12:41 PST
From: Gregor.pa@Xerox.COM
Subject: New Class Organization for CLOS Kernel
To: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
cc: common-lisp-object-system@SAIL.STANFORD.EDU
Fcc: BD:>Gregor>mail>outgoing-mail-1.text
In-Reply-To: <19871228205157.8.MOON@EUPHRATES.SCRC.Symbolics.COM>
Message-ID: <880105124145.0.GREGOR@SPIFF.parc.xerox.com>
Line-fold: no
Date: Mon, 28 Dec 87 15:51 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Date: 23 Dec 87 14:34 PST
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
The following is my understanding of what we agreed to in Cambridge.
Agreed, except for some problems with the class relationships:
standard-accessor-method and standard-method should be disjoint for the
same reason that standard-class, built-in-class, and structure-class are
now disjoint. The principle underlying this is that we need to
distinguish between the class that is used by default by the various
macros, and the class from which other classes inherit. This allows a
programmer defining a new method to choose whether this method is to be
applicable to the default kind of object that the macros make or to all
objects (of the relevant general kind). For example, standard-class is
distinct from structure-class, and they both inherit from class, so that
a programmer can put a method on standard-class to affect classes made
by defclass, or on class to affect all classes. Probably this principle
should be in your list of principles.
I agree with this principle, but I don't see why
standard-accessor-method should be disjoint from standard-method. It
seems to me that standard-accessor-method is a kind of method a lot like
standard-method. It has qualifiers and specializers, it has a method
function. It may also have some other information like slot-name or
other implementation specific stuff but all in all it seems a lot like
standard method. It definitely seems to be a specialization of
standard-method. I guess my question is, given:
(defclass method () ..)
(defclass standard-method (method) ..)
(defclass standard-accessor-method (standard-method) ..)
What methods could you want to put on standard-method that you wouldn't
want standard-accessor-method to inherit. It seems to me that for any
cases like that what you really want to do is make another subclass of
either standard-method or method and put your methods there.
It's okay for funcallable-standard-class to be a
subclass of standard-class if we really mean that
funcallable-standard-class is a specialization of the class you get with
defclass, not something distinct that wants to inherit some of the same
methods. I haven't seen a written description of funcallable-standard-class
yet, but my understanding is that that is the nature of it.
That's the nature of it.
-------
∂05-Jan-88 1256 Common-Lisp-Object-System-mailer Standardizing the macroexpansion of make-method-call
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 5 Jan 88 12:56:16 PST
Received: from Semillon.ms by ArpaGateway.ms ; 05 JAN 88 12:56:43 PST
Date: Tue, 5 Jan 88 12:54 PST
From: Gregor.pa@Xerox.COM
Subject: Standardizing the macroexpansion of make-method-call
To: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
cc: Common-Lisp-Object-System@SAIL.STANFORD.EDU
Fcc: BD:>Gregor>mail>outgoing-mail-1.text
In-Reply-To: <19871229034700.8.MOON@EUPHRATES.SCRC.Symbolics.COM>
Message-ID: <880105125449.1.GREGOR@SPIFF.parc.xerox.com>
Line-fold: no
Date: Mon, 28 Dec 87 22:47 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Gregor pointed out that in order to be able to analyze effective method
forms, which is something we claim can be done, it is necessary to be
able to recognize the macroexpansion of MAKE-METHOD-CALL. This is true.
This message is a fairly long discussion of the issues. You needn't
include all of it in replies.
I see three possible approaches:
Offhand, I prefer approach 3 although the gruesomeness of the examples
is pretty frightening. I think I want to think about this a bit more.
The purpose of this message is to say that we also need some facility
which lets the user call a random function on the same arguments the
generic function received. This facility might be called
MAKE-FUNCTION-CALL or FUNCTION-CALL or hopefully we could come up with a
better name. We have seen several examples of people who want a method
combination type which performs some specific behavior as part of the
combined method but that behavior needs access to the arguments to the
generic function.
Inventing this might even lead us out of the mess we have with
make-method-call because it might force us to come up with a real
abstraction for 'captured calls' and for 'access to the generic function
arguments'.
More on this later if I can think of anything, I sent this now hoping it
might help someone else think of something.
-------
∂06-Jan-88 1313 Common-Lisp-Object-System-mailer Re: New Specializers For CLOS
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 6 Jan 88 13:13:05 PST
Received: from Cabernet.ms by ArpaGateway.ms ; 06 JAN 88 13:13:10 PST
Date: 6 Jan 88 13:12 PST
Sender: bobrow.pa@Xerox.COM
From: Danny bobrow <bobrow.pa@Xerox.COM>
Subject: Re: New Specializers For CLOS
In-reply-to: kempf%hplabsz@hplabs.HP.COM's message of Mon, 28 Dec 87 11:38:45
MST
To: kempf%hplabsz@hplabs.HP.COM
cc: Bobrow.pa@Xerox.COM, common-lisp-object-system@SAIL.STANFORD.EDU
Message-ID: <880106-131310-5662@Xerox>
> Proposal:
> Add a specializer form
> (metaclass <class>)
> A method with such a specializer would be applicable if the metaclass of the
> object bound to the argument is of type specified by <class>.
> Proposal:
> Add a specializer
> (subclass <class>)
> A method with a subclass specializer on an argument is applicable if the
> argument is of type <class> and is a subtype of the given class.
jak says:
The outlined problems are largely in Chapter 3 and the
suggested solution will impact Chapters 1 & 2 as well. It might be
better to look for a solution which does not impact Chapters 1 & 2,
to avoid having to retrofit the changes.
Since one of the characteristics of these new specializers
outlined in the proposal was that all methods on a generic
function must agree on these new specializers (i.e. either have
them or the regular set, but not both), a new class of generic
function is suggested and, with it, perhaps a set of associated
macros (DEFINE-METACLASS-METHOD ?) for conveniently defining the
methods.
This can't be the case since you can have these kinds of specializers mixed with
ordinary specializers e.g.
(defmethod slot-value ((obj (metaclass standard-class))(name (eql 'foo)))
...)
The most compelling example for the "metaclass" specializer that we have come up
with is slot-value; but slot-value-using-class allows specialization on
either/both the metaclass and class. This can be important in some cases. Here
is a simple example.
(defmethod slot-value-using-class
((class standard-class) (object monitored-object) slot-name)
(wait-until-object-is-not-write-locked object)
(call-next-method))
Thus I think it is useful to continue to have slot-value-using-class. In this
case, and because the new specializers affect chapters 1 and 2, I would say we
should leave these out, and keep in class-prototype and <x>-using-class
∂07-Jan-88 1055 Common-Lisp-Object-System-mailer CALL-NEXT-METHOD
To: common-lisp-object-system@SAIL.Stanford.EDU
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>
Jim Kempf would like to invoke a more general method but not specifically
the next method via CALL-NEXT-METHOD.
This could be done by invoking the generic function again if there were
some way to tell CLASS-OF to consider that instances of class C1 are
instances of a superclass C2 or if there were some linguistic means of
indicating this at generic function invocation time. That is, if C2 is
a superclass of C1 and I1 is an instance of C1, then one could invoke a
more general method if you could specifiy that I1 should be considered a
direct instance of C2 (assuming C2 is the correct level of generality).
For instance,
(defmethod f ((c c1)) 'c1)
(defmethod f ((c c2)) 'c2)
(setq i (make-instance 'c1))
(f i) => c1
(f (the c2 i)) => c2
However, CALL-NEXT-METHOD does not seem the proper mechanism for
this.
-rpg-
∂07-Jan-88 1502 Common-Lisp-Object-System-mailer Re: CALL-NEXT-METHOD
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 7 Jan 88 15:02:36 PST
Received: from Cabernet.ms by ArpaGateway.ms ; 07 JAN 88 15:00:44 PST
Date: 7 Jan 88 14:59 PST
Sender: bobrow.pa@Xerox.COM
From: Danny bobrow <bobrow.pa@Xerox.COM>
Subject: Re: CALL-NEXT-METHOD
In-reply-to: Dick Gabriel <RPG@SAIL.Stanford.EDU>'s message of 07 Jan 88 10:55
PST
To: RPG@SAIL.Stanford.EDU
cc: common-lisp-object-system@SAIL.Stanford.EDU
Message-ID: <880107-150044-7614@Xerox>
Jim Kempf would like to invoke a more general method but not
specifically the next method via CALL-NEXT-METHOD.
I hadn't understood that this is what Jim wanted. I thought it was a
misunderstanding of what would happen with call-next-method.
This could be done by invoking the generic function again if there were
some way to tell CLASS-OF to consider that instances of class C1
are instances of a superclass C2 or if there were some linguistic
means of indicating this at generic function invocation time. That
is, if C2 is a superclass of C1 and I1 is an instance of C1, then
one could invoke a more general method if you could specifiy that
I1 should be considered a direct instance of C2 (assuming C2 is the
correct level of generality).
For instance,
(defmethod f ((c c1)) 'c1) (defmethod f ((c c2)) 'c2)
(setq i (make-instance 'c1))
(f i) => c1 (f (the c2 i)) => c2
However, CALL-NEXT-METHOD does not seem the proper mechanism
for this.
I agree. If we want to support this feature in the standard (Henry Lieberman
has argued for a facility like this), I think we need a construct more like:
(funcall-qua #'f (the c2 i))
where the funcall-qua is the responsible mechanism for interpreting construct
like "the".
danny
∂07-Jan-88 1652 Common-Lisp-Object-System-mailer Chapter 3 and the Cambridge Meeting
To: common-lisp-object-system@SAIL.Stanford.EDU
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>
Here is a brief summary of what I think are the important points
of my feelings about chapter 3, some of which were expressed poorly
in Cambridge last month:
1. I believe a specification that is mute on the topics covered in
chapter 3 is not acceptable.
2. I believe that the material that Danny and Gregor put together for our
meeting is acceptable (with the problems we discussed in Cambridge
resolved) if there is a careful statement about what degree of alterations
the meta-object procotol is able to achieve. I think we saw enough
variations on object-oriented programming in Cambridge to see that it is
possibly unrealistic to expect to completely parameterize the meta-object
level while achieving expressibility of (possibly unforseen)
optimizations.
However, there is a degree of variability that we can achieve with the
current level of protocol, which I believe is necessary to present.
3. I want to make sure that we have a reasonable version of chapters 1 and
2 to present to X3J13 for the next meeting, which is why I insisted we
spend the 3 hours getting it out of the way in Cambridge before the
Chapter 3 discussion. I expect to have Moon's comments incorporated into
Chapter 1 by the end of mext week (2 writing projects are ahead of it on
the queue), and I will place it out on SAIL at that time.
4. I liked Danny and Gregor's proposed new outline reasonably well. My
only question was whether some of the class-centered operations really
were class-specific or could be generalized to instances - for example,
propagate-class-update and update-class-locally. I would also favor
a reduced-ambition proposal that only revealed some important parts of
the mechanism.
-rpg-
∂07-Jan-88 1835 Common-Lisp-Object-System-mailer CALL-NEXT-METHOD
Received: from LABREA.STANFORD.EDU by SAIL.STANFORD.EDU with TCP; 7 Jan 88 18:35:38 PST
Received: by labrea.stanford.edu; Thu, 7 Jan 88 18:35:42 PST
Received: from bhopal.lucid.com by edsel id AA05075g; Thu, 7 Jan 88 18:30:15 PST
Received: by bhopal id AA19088g; Thu, 7 Jan 88 18:32:38 PST
Date: Thu, 7 Jan 88 18:32:38 PST
From: Jon L White <edsel!jonl@labrea.stanford.edu>
Message-Id: <8801080232.AA19088@bhopal.lucid.com>
To: labrea!bobrow.pa%Xerox.COM@labrea.stanford.edu
Cc: labrea!common-lisp-object-system%SAIL@labrea.stanford.edu
In-Reply-To: Danny bobrow's message of 7 Jan 88 14:59 PST <880107-150044-7614@Xerox>
Subject: CALL-NEXT-METHOD
re: funcall-qua
In the smalltalk-like object system that Bob Kerns and I did for PDP10
MacLisp and NIL in 1980 (called the EXTEND feature), we actually included
a primitive named SEND-AS. This function took just one more argument than
SEND, and defeated the CLASS-OF lookup that a normal SEND would do; it
supplied the starting point for method-lookup directly.
I realize that with multi-methods and generic functions, the syntax for
such a thing would be tricker -- maybe not even workable at all. But the
actual use of SEND-AS was for "delegation"; and if that is the intended use
that Kempf and Gabriel have in mind, then perhaps a more limited extension
is all that is needed.
-- JonL --
P.S.: R.I.P. EXTEND. It had multiple inheritance, but no method combination.
The first flavors implemetations for NIL were built on top of it, and
another non-flavor system that some MacSyma'ers wanted to play with
also went "on top" of it. But by 1983 there was a "rush to judgement"
in favor of FLAVORS; and KMP in particular helped discourage further
use by excising the documentation out of the revised MacLisp manual.
But the hooks for it are still in there, in about 30 primitive functions
like EQUAL, COPY, PURCOPY (used by compiled-code loader) etc.
∂11-Jan-88 1652 Common-Lisp-Object-System-mailer call-method proposal
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 11 Jan 88 16:52:15 PST
Received: from Semillon.ms by ArpaGateway.ms ; 11 JAN 88 16:06:12 PST
Date: Mon, 11 Jan 88 16:05 PST
From: Gregor.pa@Xerox.COM
Subject: call-method proposal
To: common-lisp-object-system@SAIL.STANFORD.EDU
Fcc: BD:>Gregor>mail>outgoing-mail-1.text
Message-ID: <880111160509.2.GREGOR@SPIFF.parc.xerox.com>
Line-fold: no
I spent some time thinking about how to solve the problem with
make-method-call and concluded that make-method-call was a really
complex little bugger. I have come up with a mechanism I believe is
simpler, on first examination it appears to be missing the single method
optimization but I believe that can be fixed quite easily.
This description is not entirely adequate, but I hope its enough to
convey the flavor of this proposal.
This proposal uses two lexical macros, CALL-METHOD and EFFECTIVE-METHOD.
These macros are lexically bound within the scope of an effective method
body. That means that the body of define-method-combination is allowed
to return code that uses these macros. Code walkers can understand
these macros quite easily, I believe their semantics is also easier for
programmers to understand.
The differences between this and make-method-call in the spec are:
- these are lexical macros
- the functionality of automatically converting lists to
combined methods provided by make-method-call is not
provided by call-method. Instead, the effective method
lexical macro must be used to declare that a form is
itself an effective method being used in the call-next-method
list.
- call-method accepts two required arguments. The method to
call is the first argument. The next methods accesible from
that method is the second argument.
- support for :operation and :identity-with-one-argument is
missing. I believe this makes things simpler. I also believe
we can get that optimization back quite easily.
The biggest difference is that I find this conceptually simpler to
understand. When I see call-method, I don't have to think about the
three different forms the first argument to make-method-call can have, I
know the first argument must be a method. I know the second argument
must be a list of methods or effective-method forms.
Here are implementations of standard and and method combination written
using this mechanism. I have read them over, I believe they are right,
but I don't have an implementation of this so I can't be sure.
(define-method-combination standard ()
((around (:around))
(before (:before))
(primary () :required t)
(after (:after)))
(let ((effective
;; This is the real method that gets run once all of the
;; :around methods have call-next-method'ed to get to it.
`(effective-method
(progn ,@(mapcar #'(lambda (m) `(call-method ,m ())) before))
(call-method ,(car primary) ,(cdr primary))
(progn ,@(mapcar #'(lambda (m) `(call-method ,m ())) after)))))
(if around
`(call-method ,(car around)
,(append (cdr around) (list effective)))
`(call-method ,effective ()))))
(define-method-combination and (&optional (order ':most-specific-first))
((around (:around))
(primary (and) :order order :required t))
(let ((effective
`(effective-method
(and (mapcar #'(lambda (m) `(call-method ,m ()))
primary)))))
(if around
`(call-method ,(car around)
,(append (cdr around) (list effective)))
`(call-method ,effective))))
-------
∂11-Jan-88 1802 Common-Lisp-Object-System-mailer CALL-NEXT-METHOD
Received: from MEAD.SCRC.Symbolics.COM ([128.81.41.234]) by SAIL.Stanford.EDU with TCP; 11 Jan 88 17:59:46 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by MEAD.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 126459; Mon 11-Jan-88 20:22:07 EST
Date: Mon, 11 Jan 88 20:22 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: CALL-NEXT-METHOD
To: Jon L White <edsel!jonl@labrea.stanford.edu>
cc: common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: <8801080232.AA19088@bhopal.lucid.com>
Message-ID: <19880112012217.5.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Thu, 7 Jan 88 18:32:38 PST
From: Jon L White <edsel!jonl@labrea.stanford.edu>
re: funcall-qua
In the smalltalk-like object system that Bob Kerns and I did for PDP10
MacLisp and NIL in 1980 (called the EXTEND feature), we actually included
a primitive named SEND-AS. This function took just one more argument than
SEND, and defeated the CLASS-OF lookup that a normal SEND would do; it
supplied the starting point for method-lookup directly.
You copied SEND-AS from the class system extant on the Lisp Machine at the
time (I'm not complaining, that was a perfectly reasonable thing to do).
Later on, SEND-AS was discredited as a bad idea that just turned programs
into messes. At least, that was the experience of the Lisp Machine folks.
I realize that with multi-methods and generic functions, the syntax for
such a thing would be tricker -- maybe not even workable at all. But the
actual use of SEND-AS was for "delegation"; and if that is the intended use
that Kempf and Gabriel have in mind, then perhaps a more limited extension
is all that is needed.
Let me be very clear: I don't think the problem with SEND-AS is the
syntax. I think the problem is that it is a way to name a function that
is different from the normal way to name functions. Instead of SEND-AS,
I prefer to say that if two methods have a subroutine in common, that
subroutine should be given a name with DEFUN in the normal way and then
they both should call it. In that old class system, and in all versions
of Flavors I am aware of, the body of a method can do things that the
body of a function can't, such as reference instance variables, which is
the argument for having a special way to name subroutines of methods
that is different from DEFUN. CLOS has fixed that.
I believe that no extension to CALL-NEXT-METHOD is desirable.
∂11-Jan-88 1917 Common-Lisp-Object-System-mailer call-method proposal prime
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 11 Jan 88 19:17:42 PST
Received: from Semillon.ms by ArpaGateway.ms ; 11 JAN 88 18:46:17 PST
Date: Mon, 11 Jan 88 18:45 PST
From: Gregor.pa@Xerox.COM
Subject: call-method proposal prime
To: common-lisp-object-system@SAIL.STANFORD.EDU
Fcc: BD:>Gregor>mail>outgoing-mail-1.text
Message-ID: <880111184514.5.GREGOR@SPIFF.parc.xerox.com>
Line-fold: no
Pavel pointed out a couple of bugs in my examples. They are fixed in
here. This message entirely supersedes the one I sent out earlier.
I spent some time thinking about how to solve the problem with
make-method-call and concluded that make-method-call was a really
complex little bugger. I have come up with a mechanism I believe is
simpler, on first examination it appears to be missing the single method
optimization but I believe that can be fixed quite easily.
This description is not entirely adequate, but I hope its enough to
convey the flavor of this proposal.
This proposal uses two lexical macros, CALL-METHOD and EFFECTIVE-METHOD.
These macros are lexically bound within the scope of an effective method
body. That means that the body of define-method-combination is allowed
to return code that uses these macros. Code walkers can understand
these macros quite easily, I believe their semantics is also easier for
programmers to understand.
The differences between this and make-method-call in the spec are:
- these are lexical macros
- the functionality of automatically converting lists to
combined methods provided by make-method-call is not
provided by call-method. Instead, the effective method
lexical macro must be used to declare that a form is
itself an effective method being used in the call-next-method
list.
- call-method accepts two required arguments. The method to
call is the first argument. The next methods accesible from
that method is the second argument.
- support for :operation and :identity-with-one-argument is
missing. I believe this makes things simpler. I also believe
we can get that optimization back quite easily.
The biggest difference is that I find this conceptually simpler to
understand. When I see call-method, I don't have to think about the
three different forms the first argument to make-method-call can have, I
know the first argument must be a method. I know the second argument
must be a list of methods or effective-method forms.
Here are implementations of standard and and method combination written
using this mechanism. I have read them over, I believe they are right,
but I don't have an implementation of this so I can't be sure.
(define-method-combination standard ()
((around (:around))
(before (:before))
(primary () :required t)
(after (:after)))
(let ((effective
;; This is the real method that gets run once all of the
;; :around methods have call-next-method'ed to get to it.
`(effective-method
(progn ,@(mapcar #'(lambda (m) `(call-method ,m ())) before))
(call-method ,(car primary) ,(cdr primary))
(progn ,@(mapcar #'(lambda (m) `(call-method ,m ())) after)))))
(if around
`(call-method ,(car around)
,(append (cdr around) (list effective)))
`(call-method ,effective ()))))
(define-method-combination and (&optional (order ':most-specific-first))
((around (:around))
(primary (and) :order order :required t))
(let ((effective
`(effective-method
(and (mapcar #'(lambda (m) `(call-method ,m ()))
primary)))))
(if around
`(call-method ,(car around)
,(append (cdr around) (list effective)))
`(call-method ,effective))))
-------
-------
∂11-Jan-88 2121 Common-Lisp-Object-System-mailer call-method proposal prime prime
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 11 Jan 88 21:21:17 PST
Received: from Semillon.ms by ArpaGateway.ms ; 11 JAN 88 21:20:04 PST
Date: Mon, 11 Jan 88 21:18 PST
From: Gregor.pa@Xerox.COM
Subject: call-method proposal prime prime
To: common-lisp-object-system@SAIL.STANFORD.EDU
Fcc: BD:>Gregor>mail>outgoing-mail-1.text
Supersedes: <880111184514.5.GREGOR@SPIFF.parc.xerox.com>
Message-ID: <880111211858.6.GREGOR@SPIFF.parc.xerox.com>
Line-fold: no
Pavel pointed out that I lost while trying to compensate for previous
lossage. At least I know Pavel is reading these messages. This message
entirely supersedes the messages I sent earlier.
I spent some time thinking about how to solve the problem with
make-method-call and concluded that make-method-call was a really
complex little bugger. I have come up with a mechanism I believe is
simpler, on first examination it appears to be missing the single method
optimization but I believe that can be fixed quite easily.
This description is not entirely adequate, but I hope its enough to
convey the flavor of this proposal.
This proposal uses two lexical macros, CALL-METHOD and EFFECTIVE-METHOD.
These macros are lexically bound within the scope of an effective method
body. That means that the body of define-method-combination is allowed
to return code that uses these macros. Code walkers can understand
these macros quite easily, I believe their semantics is also easier for
programmers to understand.
The differences between this and make-method-call in the spec are:
- these are lexical macros
- the functionality of automatically converting lists to
combined methods provided by make-method-call is not
provided by call-method. Instead, the effective method
lexical macro must be used to declare that a form is
itself an effective method being used in the call-next-method
list.
- call-method accepts two required arguments. The method to
call is the first argument. The next methods accesible from
that method is the second argument.
- support for :operation and :identity-with-one-argument is
missing. I believe this makes things simpler. I also believe
we can get that optimization back quite easily.
The biggest difference is that I find this conceptually simpler to
understand. When I see call-method, I don't have to think about the
three different forms the first argument to make-method-call can have, I
know the first argument must be a method. I know the second argument
must be a list of methods or effective-method forms.
Here are implementations of standard and and method combination written
using this mechanism. I have read them over, I believe they are right,
but I don't have an implementation of this so I can't be sure.
(define-method-combination standard ()
((around (:around))
(before (:before))
(primary () :required t)
(after (:after)))
(let ((effective
;; This is the real method that gets run once all of the
;; :around methods have call-next-method'ed to get to it.
`(effective-method
(multiple-value-prog1
(progn
,@(mapcar #'(lambda (m) `(call-method ,m ()))
before)
(call-method ,(car primary) ,(cdr primary)))
,@(mapcar #'(lambda (m) `(call-method ,m ()))
(reverse after))))))
(if around
`(call-method ,(car around)
,(append (cdr around) (list effective)))
`(call-method ,effective ()))))
(define-method-combination and (&optional (order ':most-specific-first))
((around (:around))
(primary (and) :order order :required t))
(let ((effective
`(effective-method
(and (mapcar #'(lambda (m) `(call-method ,m ()))
primary)))))
(if around
`(call-method ,(car around)
,(append (cdr around) (list effective)))
`(call-method ,effective))))
-------
∂11-Jan-88 2212 Common-Lisp-Object-System-mailer call-method proposal prime prime
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 11 Jan 88 21:21:17 PST
Received: from Semillon.ms by ArpaGateway.ms ; 11 JAN 88 21:20:04 PST
Date: Mon, 11 Jan 88 21:18 PST
From: Gregor.pa@Xerox.COM
Subject: call-method proposal prime prime
To: common-lisp-object-system@SAIL.STANFORD.EDU
Fcc: BD:>Gregor>mail>outgoing-mail-1.text
Supersedes: <880111184514.5.GREGOR@SPIFF.parc.xerox.com>
Message-ID: <880111211858.6.GREGOR@SPIFF.parc.xerox.com>
Line-fold: no
Pavel pointed out that I lost while trying to compensate for previous
lossage. At least I know Pavel is reading these messages. This message
entirely supersedes the messages I sent earlier.
I spent some time thinking about how to solve the problem with
make-method-call and concluded that make-method-call was a really
complex little bugger. I have come up with a mechanism I believe is
simpler, on first examination it appears to be missing the single method
optimization but I believe that can be fixed quite easily.
This description is not entirely adequate, but I hope its enough to
convey the flavor of this proposal.
This proposal uses two lexical macros, CALL-METHOD and EFFECTIVE-METHOD.
These macros are lexically bound within the scope of an effective method
body. That means that the body of define-method-combination is allowed
to return code that uses these macros. Code walkers can understand
these macros quite easily, I believe their semantics is also easier for
programmers to understand.
The differences between this and make-method-call in the spec are:
- these are lexical macros
- the functionality of automatically converting lists to
combined methods provided by make-method-call is not
provided by call-method. Instead, the effective method
lexical macro must be used to declare that a form is
itself an effective method being used in the call-next-method
list.
- call-method accepts two required arguments. The method to
call is the first argument. The next methods accesible from
that method is the second argument.
- support for :operation and :identity-with-one-argument is
missing. I believe this makes things simpler. I also believe
we can get that optimization back quite easily.
The biggest difference is that I find this conceptually simpler to
understand. When I see call-method, I don't have to think about the
three different forms the first argument to make-method-call can have, I
know the first argument must be a method. I know the second argument
must be a list of methods or effective-method forms.
Here are implementations of standard and and method combination written
using this mechanism. I have read them over, I believe they are right,
but I don't have an implementation of this so I can't be sure.
(define-method-combination standard ()
((around (:around))
(before (:before))
(primary () :required t)
(after (:after)))
(let ((effective
;; This is the real method that gets run once all of the
;; :around methods have call-next-method'ed to get to it.
`(effective-method
(multiple-value-prog1
(progn
,@(mapcar #'(lambda (m) `(call-method ,m ()))
before)
(call-method ,(car primary) ,(cdr primary)))
,@(mapcar #'(lambda (m) `(call-method ,m ()))
(reverse after))))))
(if around
`(call-method ,(car around)
,(append (cdr around) (list effective)))
`(call-method ,effective ()))))
(define-method-combination and (&optional (order ':most-specific-first))
((around (:around))
(primary (and) :order order :required t))
(let ((effective
`(effective-method
(and (mapcar #'(lambda (m) `(call-method ,m ()))
primary)))))
(if around
`(call-method ,(car around)
,(append (cdr around) (list effective)))
`(call-method ,effective))))
-------
∂12-Jan-88 2006 Common-Lisp-Object-System-mailer defmethod-setf
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 12 Jan 88 20:06:23 PST
Received: from Semillon.ms by ArpaGateway.ms ; 12 JAN 88 19:17:21 PST
Date: Tue, 12 Jan 88 19:16 PST
From: Gregor.pa@Xerox.COM
Subject: defmethod-setf
To: common-lisp-object-system@SAIL.STANFORD.EDU
Fcc: BD:>Gregor>mail>outgoing-mail-1.text
Message-ID: <880112191617.4.GREGOR@SPIFF.parc.xerox.com>
Line-fold: no
A while ago, we developed a proposal for real setf functions and a
simple rule for when setf should expand into a call to them. That
proposal was well received by the cleanup committee. Given that
proposal, people can program like this:
(defun foo (x) (gethash x *foo*))
(defun (foo setf) (nv x) (setf (gethash x *foo*) nv))
Which is great.
I think we should get rid of defmethod-setf and defgeneric-setf. I
think they are just superfluous and confusing.
-------
∂12-Jan-88 2215 Common-Lisp-Object-System-mailer CALL-NEXT-METHOD and funcall-qua/send-as
Received: from labrea.Stanford.EDU by SAIL.Stanford.EDU with TCP; 12 Jan 88 22:15:21 PST
Received: by labrea.Stanford.EDU; Tue, 12 Jan 88 22:15:21 PST
Received: from bhopal.lucid.com by edsel id AA27808g; Tue, 12 Jan 88 22:06:00 PST
Received: by bhopal id AA15662g; Tue, 12 Jan 88 22:08:44 PST
Date: Tue, 12 Jan 88 22:08:44 PST
From: Jon L White <edsel!jonl@labrea.Stanford.EDU>
Message-Id: <8801130608.AA15662@bhopal.lucid.com>
To: labrea!Moon%STONY-BROOK.SCRC.Symbolics.COM@labrea.Stanford.EDU
Cc: labrea!common-lisp-object-system%SAIL@labrea.Stanford.EDU
In-Reply-To: David A. Moon's message of Mon, 11 Jan 88 20:22 EST <19880112012217.5.MOON@EUPHRATES.SCRC.Symbolics.COM>
Subject: CALL-NEXT-METHOD and funcall-qua/send-as
re: . . . In that old class system, and in all versions
of Flavors I am aware of, the body of a method can do things that the
body of a function can't, such as reference instance variables, which is
the argument for having a special way to name subroutines of methods
that is different from DEFUN.
An explicit goal of the EXTEND system was to unify the functional programming
syntax with a smalltalk like class system; indeed, the early versions of
the Lisp Machine CLASS system (and even FLAVORS) were so much like smalltalk
that they perpetuated the special metavariable status of 'self' (and 'super'
too, I think?) and thus didn't look like functions. [Instance variables
were referenced with normal macros, since pdp10 Maclisp didn't support
"symbol macros"].
CLOS follows the EXTEND lead here.
As to how this relates to the funcall-qua/send-as issue -- the motivating
problem was really ease of implementing "delagation". This is probably best
not handled as a kludge on CALL-NEXT-METHOD; however, maybe some thought
out to be given to this area in the concepts section of the spec?
On the other hand, you seem to be concerned about the more general problem of
code-sharing in your comment:
the problem [with SEND-AS] is that it is a way to name a function that
is different from the normal way to name functions. Instead of SEND-AS,
I prefer to say that if two methods have a subroutine in common, that
subroutine should be given a name with DEFUN in the normal way and then
they both should call it. . . .
I don't think this is releated to "delegation". Do you?
-- JonL --
∂13-Jan-88 0821 Common-Lisp-Object-System-mailer is the functi.dvi file trashed?
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 13 Jan 88 08:21:54 PST
Received: from JUNCO.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 320057; Wed 13-Jan-88 11:21:58 EST
Date: Wed, 13 Jan 88 11:21 EST
From: Sonya E. Keene <skeene@STONY-BROOK.SCRC.Symbolics.COM>
Subject: is the functi.dvi file trashed?
To: common-lisp-object-system@SAIL.STANFORD.EDU
Message-ID: <19880113162140.4.SKEENE@JUNCO.SCRC.Symbolics.COM>
When I print it, it looks completely trashed. Could someone reformat
it? Thanks.
∂13-Jan-88 0926 Common-Lisp-Object-System-mailer Re: defmethod-setf
Received: from RELAY.CS.NET by SAIL.Stanford.EDU with TCP; 13 Jan 88 09:26:26 PST
Received: from relay2.cs.net by RELAY.CS.NET id aa22672; 13 Jan 88 11:37 EST
Received: from csc.ti.com by RELAY.CS.NET id aa06619; 13 Jan 88 11:27 EST
Received: from Jenner by tilde id AA07755; Wed, 13 Jan 88 07:16:55 CST
Message-Id: <2778067032-7820945@Jenner>
Date: Wed, 13 Jan 88 07:17:12 CST
From: Patrick H Dussud <DUSSUD%jenner.csc.ti.com@RELAY.CS.NET>
To: Gregor.pa@XEROX.COM
Cc: common-lisp-object-system@SAIL.STANFORD.EDU
Subject: Re: defmethod-setf
In-Reply-To: Msg of Tue, 12 Jan 88 19:16 PST from Gregor.pa@xerox.com
Date: Tue, 12 Jan 88 19:16 PST
From: Gregor.pa@xerox.com
Subject: defmethod-setf
A while ago, we developed a proposal for real setf functions and a
simple rule for when setf should expand into a call to them. That
proposal was well received by the cleanup committee. Given that
proposal, people can program like this:
(defun foo (x) (gethash x *foo*))
(defun (foo setf) (nv x) (setf (gethash x *foo*) nv))
Which is great.
I think we should get rid of defmethod-setf and defgeneric-setf. I
think they are just superfluous and confusing.
-------
I agree with this. As a matter of fact, I thought we already got rid of
them.
Patrick.
∂13-Jan-88 1003 Common-Lisp-Object-System-mailer Re: defmethod-setf
Received: from RELAY.CS.NET by SAIL.Stanford.EDU with TCP; 13 Jan 88 09:26:26 PST
Received: from relay2.cs.net by RELAY.CS.NET id aa22672; 13 Jan 88 11:37 EST
Received: from csc.ti.com by RELAY.CS.NET id aa06619; 13 Jan 88 11:27 EST
Received: from Jenner by tilde id AA07755; Wed, 13 Jan 88 07:16:55 CST
Message-Id: <2778067032-7820945@Jenner>
Date: Wed, 13 Jan 88 07:17:12 CST
From: Patrick H Dussud <DUSSUD%jenner.csc.ti.com@RELAY.CS.NET>
To: Gregor.pa@XEROX.COM
Cc: common-lisp-object-system@SAIL.STANFORD.EDU
Subject: Re: defmethod-setf
In-Reply-To: Msg of Tue, 12 Jan 88 19:16 PST from Gregor.pa@xerox.com
Date: Tue, 12 Jan 88 19:16 PST
From: Gregor.pa@xerox.com
Subject: defmethod-setf
A while ago, we developed a proposal for real setf functions and a
simple rule for when setf should expand into a call to them. That
proposal was well received by the cleanup committee. Given that
proposal, people can program like this:
(defun foo (x) (gethash x *foo*))
(defun (foo setf) (nv x) (setf (gethash x *foo*) nv))
Which is great.
I think we should get rid of defmethod-setf and defgeneric-setf. I
think they are just superfluous and confusing.
-------
I agree with this. As a matter of fact, I thought we already got rid of
them.
Patrick.
∂13-Jan-88 1009 Common-Lisp-Object-System-mailer defmethod-setf
To: gregor@XEROX.COM
CC: common-lisp-object-system@SAIL.Stanford.EDU
From: Linda DeMichiel <LGD@SAIL.Stanford.EDU>
defmethod-setf and defgeneric-setf were flushed several months ago.
-lgd
∂13-Jan-88 1038 Common-Lisp-Object-System-mailer Re: Method Combination Objects
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 13 Jan 88 10:37:40 PST
Received: from Cabernet.ms by ArpaGateway.ms ; 13 JAN 88 10:36:39 PST
Date: 13 Jan 88 10:36 PST
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Re: Method Combination Objects
In-reply-to: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>'s message of
Tue, 29 Dec 87 17:27 EST
To: Moon@STONY-BROOK.SCRC.Symbolics.COM
cc: Common-Lisp-Object-System@SAIL.STANFORD.EDU
Message-ID: <880113-103639-2495@Xerox>
I have no problem at all with the Method Combination Object Layer. It seems
just right.
Here is an alternative proposal for a "naming" layer.
There is a generic function:
(defgeneric method-combination-instance
(generic-function method-combination &key options) ...)
This generic function combines the capabilities of method-combination-maker and
the application of the resulting function to produce the method combination
object.
(method-combination-instance g-fn name :options options)
is how a method combination name and options are converted into an object.
(defmethod method-combination-instance
((g-fn standard-generic-function)
(name (eql '<name>)
&key options)
....)
is how a method combination type is defined.
remove-method is how it is undefined.
Comparison to method-combination-maker
It has the same advantages with respect to:
1) It provides a separate name space for method combination names.
2) Several method combination types might share a single class.
3) A call to method-combination-instance might return the same
object each time it is called, instead of making a new object.
Advantages of method-combination-instance:
It uses a mechanism already in CLOS, namely methods on individuals, and does not
add a new function for associating a name with an object, or a way to unset that
association.
It allows specialization on the class of the generic function as well as on the
name. Although useful, this might not be important because
compute-effective-method also allows specialization on both the generic function
and method combination object.
Disadvantage:
As pointed out by Moon:
The options seen in the :method-combination option to defgeneric
are defined by a lambda-list in define-method-combination, rather
than being just keyword arguments. ... Passing the whole
list of options as one :options initialization argument, we wouldn't
be exploiting any Lisp mechanism to parse the options.
As Moon points out we could change the options arguments into keywords.
Alternatively, this can be programmed around by using an application of a
lambda-list internal to the method to check the arguments.
In Moons message, he provides the following macro definition:
(defmacro define-method-combination
(name &key (documentation nil)
(operator name)
(identity-with-one-argument nil))
`(setf (method-combination-maker ',name)
#'(lambda (&optional (order ':most-specific-first))
(make-instance 'short-form-method-combination
'name ',name
'order order
'documentation ',documentation
'operator ',operator
'identity-with-one-argument ',identity-with-one-argument))))
The comparable code is approximately:
(defmacro define-method-combination
(name &key (documentation nil)
(operator name)
(identity-with-one-argument nil))
`(defmethod method-combination-instance
((g-fn standard-generic-function) (eql ',name) &key options)
(apply
#'(lambda (&optional (order ':most-specific-first))
(make-instance 'short-form-method-combination
'name ',name
'order order
'documentation ',documentation
'operator ',operator
'identity-with-one-argument ',identity-with-one-argument))
options)))
∂13-Jan-88 1240 Common-Lisp-Object-System-mailer Defmethod-setf
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 13 Jan 88 12:39:25 PST
Received: from Semillon.ms by ArpaGateway.ms ; 13 JAN 88 10:53:45 PST
Date: Wed, 13 Jan 88 10:52 PST
From: Gregor.pa@Xerox.COM
Subject: Defmethod-setf
To: Dick Gabriel <RPG@SAIL.STANFORD.EDU>
cc: common-lisp-object-system@SAIL.STANFORD.EDU
Fcc: BD:>Gregor>mail>outgoing-mail-1.text
In-Reply-To: The message of 13 Jan 88 08:04 PST from Dick Gabriel
<RPG@SAIL.Stanford.EDU>
Message-ID: <880113105230.8.GREGOR@SPIFF.parc.xerox.com>
Line-fold: no
Oops, I am on mars. We already flushed defmethod-setf and friends.
Well I knew it was a good idea.
Gregor
-------
∂13-Jan-88 1437 Common-Lisp-Object-System-mailer functi.dvi
To: skeene@SCRC-STONY-BROOK.ARPA
CC: common-lisp-object-system@SAIL.Stanford.EDU
From: Linda DeMichiel <LGD@SAIL.Stanford.EDU>
I retexed functi and as far as I can tell the .dvi file is fine.
Sail has been having arpanet trouble lately, so perhaps there was
ftp lossage in the copy you got.
Note: the current copy on sail pre-dates our Cambridge meeting.
I'll be putting out a new copy to reflect recent comments around
the beginning of next week.
-l
∂13-Jan-88 1716 Common-Lisp-Object-System-mailer Sonya's problem with functi.dvi
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 13 Jan 88 17:16:00 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 320557; Wed 13-Jan-88 20:15:38 EST
Date: Wed, 13 Jan 88 20:15 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Sonya's problem with functi.dvi
To: common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: The message of 13 Jan 88 17:37 EST from Linda DeMichiel <LGD@SAIL.Stanford.EDU>
Message-ID: <19880114011548.2.MOON@EUPHRATES.SCRC.Symbolics.COM>
The source of at least the immediate symptom turned out to be that someone
had trashed the information about SAIL.STANFORD.EDU in the Internet domain
database, specifically what operating system it runs. Since this is a
distributed database with no audit trails, it's a bit difficult to find
out who was responsible. We have a way to get around it, now that we
know that that was the problem.
∂14-Jan-88 0656 Common-Lisp-Object-System-mailer Re: add-method when method exists
Received: from RELAY.CS.NET by SAIL.Stanford.EDU with TCP; 14 Jan 88 06:56:27 PST
Received: from relay2.cs.net by RELAY.CS.NET id aa07671; 14 Jan 88 9:52 EST
Received: from csc.ti.com by RELAY.CS.NET id aa13381; 14 Jan 88 9:42 EST
Received: from Jenner by tilde id AA04504; Thu, 14 Jan 88 08:14:42 CST
Message-Id: <2778156951-13219609@Jenner>
Date: Thu, 14 Jan 88 08:15:51 CST
From: Patrick H Dussud <DUSSUD%jenner.csc.ti.com@RELAY.CS.NET>
To: common-lisp-object-system@SAIL.STANFORD.EDU
Subject: Re: add-method when method exists
In-Reply-To: Msg of Mon, 28 Dec 87 14:53 EST from "David A. Moon" <Moon@scrc-stony-brook.arpa>
Date: Mon, 28 Dec 87 14:53 EST
From: "David A. Moon" <Moon@scrc-stony-brook.arpa>
Subject: Re: add-method when method exists
3)Should add-method become add-or-replace-method
I agree with the semantics, I would propose to keep the name as simple as possible.
If we qualify the name, people will expect to find other variations like
add-or-complain-method....
4) Precisely when are errors signaled
Since we allow forward references for classes, we need to allow illegal states
for generic functions temporarily.
The following code should be allowed:
(defgeneric trash (object)
(:documentation "destroy the contents of object"))
(defclass foo (bar) ...)
(defmethod trash :after ((object foo))
...)
(defclass bar () ...)
(defmethod trash ((object bar))
...)
At least add-method shouldn't complain if a daemon method is added and there is no
primary method.
Patrick.
∂14-Jan-88 2008 Common-Lisp-Object-System-mailer Re: Method Combination Objects
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 14 Jan 88 20:08:24 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 321328; Thu 14-Jan-88 22:57:53 EST
Date: Thu, 14 Jan 88 22:57 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: Method Combination Objects
To: Common-Lisp-Object-System@SAIL.STANFORD.EDU
In-Reply-To: <880113-103639-2495@Xerox>
Message-ID: <19880115035749.6.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: 13 Jan 88 10:36 PST
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
I have no problem at all with the Method Combination Object Layer. It seems
just right.
Here is an alternative proposal for a "naming" layer.
(method-combination-instance g-fn name :options options)
is how a method combination name and options are converted into an object.
This looks good to me except for two fairly minor points. One is that
I think the options should be a required argument rather than a keyword
argument. There is no reason ever to omit this. Secondly, I'm not
sure about the name method-combination-instance; it doesn't seem consistent
with the rest of chapter 3. I don't know if you've changed the naming
conventions since the last version I saw, but in that version the
consistent name would be something like expand-method-combination.
Personally I prefer parse-xxx for names of functions that convert
specifications into objects, rather than expand-xxx.
Let me know what name is consistent with what you're doing and I'll mail
out a modified proposal when I get a chance.
∂14-Jan-88 2008 Common-Lisp-Object-System-mailer call-method proposal prime prime
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 14 Jan 88 20:08:06 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 321324; Thu 14-Jan-88 22:40:43 EST
Date: Thu, 14 Jan 88 22:40 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: call-method proposal prime prime
To: common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: <880111211858.6.GREGOR@SPIFF.parc.xerox.com>
Message-ID: <19880115034035.4.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Mon, 11 Jan 88 21:18 PST
From: Gregor.pa@Xerox.COM
I spent some time thinking about how to solve the problem with
make-method-call and concluded that make-method-call was a really
complex little bugger. I have come up with a mechanism I believe is
simpler,
This is pretty similar to a mechanism we rejected a year or so ago, which
is where MAKE-METHOD-CALL came from. However, I think we made a mistake
back then, and I'm happy with your proposed mechanism, except for a couple
of details I'll note below.
We're running low on time to decide to adopt this and update the
documentation accordingly; can we make a quick decision? I guess I
can volunteer to help with the rewriting of existing text, if needed.
on first examination it appears to be missing the single method
optimization but I believe that can be fixed quite easily.
The technique that MAKE-METHOD-CALL used can't work here. We simply
have to decide whether it's the responsibility of the method-combination
function or of programs that analyze effective-method forms to know that
AND with one subform can be optimized. They also have to know about
PROGN, MULTIPLE-VALUE-PROG1, etc. Either way will work and is easy
enough to do. In Flavors it's the responsibility of the analyzing
programs rather than the synthesizing programs, so that's my suggestion.
Either way, the CLOS specification must be explicit about this.
This proposal uses two lexical macros, CALL-METHOD and EFFECTIVE-METHOD.
These macros are lexically bound within the scope of an effective method
body. That means that the body of define-method-combination is allowed
to return code that uses these macros. Code walkers can understand
these macros quite easily, I believe their semantics is also easier for
programmers to understand.
- call-method accepts two required arguments. The method to
call is the first argument. The next methods accesible from
that method is the second argument.
This doesn't distinguish between "no next method" and "call-next-method
not allowed." MAKE-METHOD-CALL made that distinction. If we need to
make that distinction, then I suggest one required argument and one
keyword argument, :NEXT-METHODS. I don't think the Symbolics
implementation will need that distinction, but I don't know about others.
Here are implementations of standard and and method combination written
using this mechanism.
They look right except for one or two comma errors. They are awfully
verbose, but I think I agree that in this particular case it's better to
be more verbose than to have a more obscure primitive for people to
learn. Much of the verbosity is caused by the expressive poverty of
Common Lisp, not by your two macros themselves. Fortunately, the short
form of define-method-combination eliminates the need for most people to
deal with the verbosity.
For fun:
(defun make-method-call (methods &key (operator 'progn)
(identity-with-one-argument
(eq operator 'progn)))
(unless (listp methods)
(setq methods (list methods)))
(let ((forms (mapcar #'(lambda (method)
(if (listp method)
method
`(call-method ,method ())))
methods))
(methods (mapcar #'(lambda (method)
(if (listp method)
`(effective-method ,method)
method))
methods)))
(cond ((eq operator ':call-next-method)
(and methods `(method-call ,(first methods) ,(rest methods))))
((and identity-with-one-argument (= (length methods) 1))
(first forms))
(t `(,operator ,@forms)))))
That wasn't so bad, was it? In fact it's the same number of lines
as your new definition of standard method combination.
∂14-Jan-88 2008 Common-Lisp-Object-System-mailer Standardizing the macroexpansion of make-method-call
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 14 Jan 88 20:08:06 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 321325; Thu 14-Jan-88 22:48:59 EST
Date: Thu, 14 Jan 88 22:48 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Standardizing the macroexpansion of make-method-call
To: Gregor.pa@Xerox.COM
cc: Common-Lisp-Object-System@SAIL.STANFORD.EDU
In-Reply-To: <880105125449.1.GREGOR@SPIFF.parc.xerox.com>
Message-ID: <19880115034855.5.MOON@EUPHRATES.SCRC.Symbolics.COM>
Line-fold: No
Date: Tue, 5 Jan 88 12:54 PST
From: Gregor.pa@Xerox.COM
....we also need some facility
which lets the user call a random function on the same arguments the
generic function received. This facility might be called
MAKE-FUNCTION-CALL or FUNCTION-CALL or hopefully we could come up with a
better name. We have seen several examples of people who want a method
combination type which performs some specific behavior as part of the
combined method but that behavior needs access to the arguments to the
generic function.
Inventing this might even lead us out of the mess we have with
make-method-call because it might force us to come up with a real
abstraction for 'captured calls' and for 'access to the generic function
arguments'.
More on this later if I can think of anything, I sent this now hoping it
might help someone else think of something.
I assume you decided we don't really need to do anything about this,
since it wasn't in your later message. If we do, here's a suggestion.
In Flavors, we just put
(:ARGLIST . lambda-list)
in front of the body of the define-method-combination, and parameter
variables in the lambda-list are bound to forms that can be inserted into
the effective-method to access the corresponding arguments to the generic
function (I guess they are gensyms or something). Extra arguments to
the generic function can be ignored.
This seems simpler for the application you described than introducing a
function call. Here's a simple example:
(define-method-combination progn-with-lock ()
((methods ()))
(:arglist object)
`(unwind-protect
(progn (lock (object-lock ,object))
,@(mapcar #'(lambda (m) `(call-method ,m ()))
methods))
(unlock (object-lock ,object))))
∂15-Jan-88 0907 Common-Lisp-Object-System-mailer Re: call-method proposal prime prime
Received: from RELAY.CS.NET by SAIL.Stanford.EDU with TCP; 15 Jan 88 09:07:29 PST
Received: from relay2.cs.net by RELAY.CS.NET id ae10723; 15 Jan 88 11:53 EST
Received: from csc.ti.com by RELAY.CS.NET id ac21503; 15 Jan 88 11:43 EST
Received: from Jenner by tilde id AA16581; Fri, 15 Jan 88 09:44:39 CST
Message-Id: <2778248738-2219223@Jenner>
Date: Fri, 15 Jan 88 09:45:38 CST
From: Patrick H Dussud <DUSSUD@jenner.csc.ti.com>
To: common-lisp-object-system@SAIL.STANFORD.EDU
Subject: Re: call-method proposal prime prime
In-Reply-To: Msg of Thu, 14 Jan 88 22:40 EST from "David A. Moon" <Moon@scrc-stony-brook.arpa>
on first examination it appears to be missing the single method
optimization but I believe that can be fixed quite easily.
The technique that MAKE-METHOD-CALL used can't work here. We simply
have to decide whether it's the responsibility of the method-combination
function or of programs that analyze effective-method forms to know that
AND with one subform can be optimized. They also have to know about
PROGN, MULTIPLE-VALUE-PROG1, etc. Either way will work and is easy
enough to do. In Flavors it's the responsibility of the analyzing
programs rather than the synthesizing programs, so that's my suggestion.
Either way, the CLOS specification must be explicit about this.
I thought the synthesizing program (the method combination function) would be the
natural place for this optimization. I say that because the short form of
DEFINE-METHOD-COMBINATION has the optimization option, :identity-with-one-arg that
enables the method function to perform the optimization.
This proposal uses two lexical macros, CALL-METHOD and EFFECTIVE-METHOD.
These macros are lexically bound within the scope of an effective method
body. That means that the body of define-method-combination is allowed
to return code that uses these macros. Code walkers can understand
these macros quite easily, I believe their semantics is also easier for
programmers to understand.
- call-method accepts two required arguments. The method to
call is the first argument. The next methods accesible from
that method is the second argument.
This doesn't distinguish between "no next method" and "call-next-method
not allowed." MAKE-METHOD-CALL made that distinction. If we need to
make that distinction, then I suggest one required argument and one
keyword argument, :NEXT-METHODS. I don't think the Symbolics
implementation will need that distinction, but I don't know about others.
Why can't we use an optional second argument instead of a keyword?, I don't think
that we want to allow extensions.
Besides these points, I am happy with Gregor's proposal. I don't think that
MAKE-METHOD-CALL will be used widely enough to justify its existence.
Patrick.
∂15-Jan-88 0923 Common-Lisp-Object-System-mailer DEFMETHOD Specification
Received: from RELAY.CS.NET by SAIL.Stanford.EDU with TCP; 15 Jan 88 09:23:08 PST
Received: from relay2.cs.net by RELAY.CS.NET id ai10935; 15 Jan 88 12:03 EST
Received: from csc.ti.com by RELAY.CS.NET id an21503; 15 Jan 88 11:48 EST
Received: from Jenner by tilde id AA17626; Fri, 15 Jan 88 10:30:49 CST
Message-Id: <2778251512-2385869@Jenner>
Date: Fri, 15 Jan 88 10:31:52 CST
From: Patrick H Dussud <DUSSUD@jenner.csc.ti.com>
To: Common-Lisp-Object-System@SAIL.STANFORD.EDU
Subject: DEFMETHOD Specification
If the DEFMETHOD spec, in the second paragraph [ If (fboundp function-specifier) is
nil], it says that the lambda-list of the [created] generic function is congruent
with the lambda-list of the method. This is not specific enough, given our rules
on lambda-list congruence.
The issue is:
If the method lambda-list contains some keys, do we create the generic function
lambda-list with these keys present? If we do, then we enforce the fact that every
method for this generic function must accept these keys.
I think that we shouldn't put them in the generic function lambda-list, but either
way, this needs to be specified.
Patrick.
∂15-Jan-88 1315 Common-Lisp-Object-System-mailer method-lambda
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 15 Jan 88 13:13:41 PST
Received: from Semillon.ms by ArpaGateway.ms ; 15 JAN 88 13:12:39 PST
Date: Fri, 15 Jan 88 13:11 PST
From: Gregor.pa@Xerox.COM
Subject: method-lambda
To: common-lisp-object-system@SAIL.STANFORD.EDU
Fcc: BD:>Gregor>mail>outgoing-mail-1.text
Message-ID: <880115131101.2.GREGOR@SPIFF.parc.xerox.com>
Line-fold: no
A problem we have never quite resolved is how to abstract out the
information about call-next-method (and slot optimization) that needs to
be passed to method functions. I have said on several occaisons that I
would like for it to be possible to apply method functions to the
'natural' arguments; I would also like it to be possible to construct
method functions. Moon has countered quite rightly that this makes it
difficult to implement call-next-method. This message proposes a
solution to this problem and proposes some significant reduction in
some contentious parts of chapter 3.
Briefly I propose that we introduce a constructs called method-lambda
and method-apply. In addition I propose that we eliminate the
defmethod parsing (and defclass parsing) parts of the mop.
method lambda is like lambda except that the functions it 'produces' are
designed to be called with method-apply. The results of calling a
method lambda with ordinary apply are undefined. There might also
have to be a method-function-p predicate.
method-apply is like apply, it takes the 'natural' arguments that
want to be passed to the method function. It does anything else that
needs to be done to call the method-function properly. I don't know
whether or not it wants to take a list of next methods, I suspect it
doesn't. call-next-method inside of the called method-function would
just say there were no next methods.
Here is some sample code.
(defun trace-gf (gf)
(let ((nargs (generic-function-required-arguments gf))
(lambda-list (generic-function-congruent-lambda-list gf))
(specializers (make-list nargs :initial-element (symbol-class 't)))
(qualifiers '(:around))
(function (compile () `(method-lambda ,lambda-list
(format *trace-output* "~&Hi there.")
(call-next-method)))))
(add-method gf
(make-instance 'standard-method
:lambda-list lambda-list
:specializers specializers
:qualifiers qualifiers
:function function))))
This code itself is kind of silly, but it shows why it must be possible
to construct a function that can be used as the function of a
standard-method. Other obvious examples (like steppers) show why it
must be possible to call a function that was constructed by defmethod.
I propose that we eliminate the defmethod parsing stuff because this
provides a significant part of the functionality that was going after
and because the defmethod parsing stuff is one of the least well worked
out parts of the mop. I do think we should be able to agree on
method-lambda, method-function-p and method-apply pretty quickly though.
-------
∂15-Jan-88 1333 Common-Lisp-Object-System-mailer Re: call-method proposal prime prime
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 15 Jan 88 13:32:54 PST
Received: from Semillon.ms by ArpaGateway.ms ; 15 JAN 88 13:32:29 PST
Date: Fri, 15 Jan 88 13:30 PST
From: Gregor.pa@Xerox.COM
Subject: Re: call-method proposal prime prime
To: Patrick H Dussud <DUSSUD@jenner.csc.ti.com>, David A. Moon
<Moon@STONY-BROOK.SCRC.Symbolics.COM>
cc: common-lisp-object-system@SAIL.STANFORD.EDU
Fcc: BD:>Gregor>mail>outgoing-mail-1.text
In-Reply-To: <2778248738-2219223@Jenner>,
<19880115034035.4.MOON@EUPHRATES.SCRC.Symbolics.COM>,
<19880115034855.5.MOON@EUPHRATES.SCRC.Symbolics.COM>,
<19880115035749.6.MOON@EUPHRATES.SCRC.Symbolics.COM>
Message-ID: <880115133053.3.GREGOR@SPIFF.parc.xerox.com>
Line-fold: no
Date: Thu, 14 Jan 88 22:40 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
We're running low on time to decide to adopt this and update the
documentation accordingly; can we make a quick decision? I guess I
can volunteer to help with the rewriting of existing text, if
needed.
With the comments I make below I am happy with this and can promise you
fast turnaround on comments for anything you write.
The technique that MAKE-METHOD-CALL used can't work here. We simply
have to decide whether it's the responsibility of the method-combination
function or of programs that analyze effective-method forms to know that
AND with one subform can be optimized. They also have to know about
PROGN, MULTIPLE-VALUE-PROG1, etc. Either way will work and is easy
enough to do. In Flavors it's the responsibility of the analyzing
programs rather than the synthesizing programs, so that's my suggestion.
Either way, the CLOS specification must be explicit about this.
I think it should be the resposibility of the analyzing program, but I
believe we should make an explicit comment that has the effect of
standardizing the 'simple' value that can be returned by the
synthesizing program. We should say that analyzing programs will catch
the case:
(call-method <m1> <whatever>)
This will make people who have some weird special function, and who want
to clue the system in to the fact that they are just returning a call to
a single method have a standard way of doing that.
This doesn't distinguish between "no next method" and "call-next-method
not allowed." MAKE-METHOD-CALL made that distinction. If we need to
make that distinction, then I suggest one required argument and one
keyword argument, :NEXT-METHODS. I don't think the Symbolics
implementation will need that distinction, but I don't know about
others.
It seems like the call-next-method not allowed distinction needs to
(mostly) be made at a different time anyways (specifically defmethod
time). But if we do make that distinction I agree with Patrick that the
argument should be optional rather than keyword.
They look right except for one or two comma errors. They are awfully
verbose, but I think I agree that in this particular case it's better to
be more verbose than to have a more obscure primitive for people to
learn. Much of the verbosity is caused by the expressive poverty of
Common Lisp, not by your two macros themselves. Fortunately, the short
form of define-method-combination eliminates the need for most people to
deal with the verbosity.
I agree.
Date: Thu, 14 Jan 88 22:48 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Date: Tue, 5 Jan 88 12:54 PST
From: Gregor.pa@Xerox.COM
....we also need some facility
which lets the user call a random function on the same arguments the
generic function received. This facility might be called
MAKE-FUNCTION-CALL or FUNCTION-CALL or hopefully we could come up with a
better name.
I assume you decided we don't really need to do anything about this,
since it wasn't in your later message. If we do, here's a suggestion.
In Flavors, we just put
(:ARGLIST . lambda-list)
I still think this is very important. I just left it out of my last
message for simplicity. Your suggestion about :arglist seems fine to
me, but I think :lambda-list is a better name.
Date: Thu, 14 Jan 88 22:57 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
This looks good to me except for two fairly minor points. One is that
I think the options should be a required argument rather than a keyword
argument. There is no reason ever to omit this. Secondly, I'm not
sure about the name method-combination-instance; it doesn't seem consistent
with the rest of chapter 3. I don't know if you've changed the naming
conventions since the last version I saw, but in that version the
consistent name would be something like expand-method-combination.
Personally I prefer parse-xxx for names of functions that convert
specifications into objects, rather than expand-xxx.
In the message I sent out moments ago, I now believe the expand-xxx
functions that were in the mop are not yet well enough understood to be
standardized. I do believe we can and should standardize this function
though; I like the name method-combination-object. I agree that the
options argument should be required rather than keyword or optional.
-------
∂15-Jan-88 1356 Common-Lisp-Object-System-mailer Re: call-method proposal prime prime
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 15 Jan 88 13:56:22 PST
Received: from Semillon.ms by ArpaGateway.ms ; 15 JAN 88 13:53:35 PST
Date: Fri, 15 Jan 88 14:22:28 PST
From: vijay <saraswat.pa@Xerox.COM>
Subject: Re: call-method proposal prime prime
In-Reply-To: <880115133053.3.GREGOR@SPIFF.parc.xerox.com>
To: Gregor.pa@Xerox.COM
cc: Patrick H Dussud <DUSSUD@jenner.csc.ti.com>, David A. Moon
<Moon@STONY-BROOK.SCRC.Symbolics.COM>,
common-lisp-object-system@SAIL.STANFORD.EDU
Message-ID: <880115-135335-5965@Xerox>
Hi Gregor: Will you take me (saraswat.pa and saraswat@c.cs.cmu.edu) off the
list please? I am afriad I have fallen too far behind to understand current
message traffic.
Vijay.
References
Gregor's message of Fri, 15 Jan 88 13:30:00 PST -- Re: call-method proposal
prime prime
∂15-Jan-88 1356 Common-Lisp-Object-System-mailer Re: Method Combination Objects
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 15 Jan 88 13:56:29 PST
Received: from Cabernet.ms by ArpaGateway.ms ; 15 JAN 88 13:53:38 PST
Date: 15 Jan 88 13:52 PST
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Re: Method Combination Objects
In-reply-to: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>'s message of
Thu, 14 Jan 88 22:57 EST
To: Moon@STONY-BROOK.SCRC.Symbolics.COM
cc: Common-Lisp-Object-System@SAIL.STANFORD.EDU
Message-ID: <880115-135338-5966@Xerox>
Date: 13 Jan 88 10:36 PST From: Danny Bobrow
<Bobrow.pa@Xerox.COM>
I have no problem at all with the Method Combination
Object Layer. It seems just right.
Here is an alternative proposal for a "naming" layer.
(method-combination-instance g-fn name :options options)
is how a method combination name and options are converted
into an object.
This looks good to me except for two fairly minor points. One
is that I think the options should be a required argument rather
than a keyword argument. There is no reason ever to omit this.
Fine with me.
Secondly, I'm not sure about the name method-combination-instance;
it doesn't seem consistent with the rest of chapter 3. I don't
know if you've changed the naming conventions since the last
version I saw, but in that version the consistent name would be
something like expand-method-combination. Personally I prefer
parse-xxx for names of functions that convert specifications into
objects, rather than expand-xxx.
I saw method-combination-instance as being parallel with the generic
function slot-description-class, since both participate in the creation
of "secondary" objects, i.e. slot-descriptions associated with a class,
and method-combination-objects associated with a generic function.
Hence the name.
In recent days Gregor has come to believe that we need not specify any
of the expand-xxx objects which are macroexpander helpers. He claims
that to change the macroexpansions users "should" write there own
macros. What is your feeling about these expand-xxx or parse-xxx
generic functions (I have become neutral on them).
Let me know what name is consistent with what you're doing and
I'll mail out a modified proposal when I get a chance.
Thank you.
∂15-Jan-88 1421 Common-Lisp-Object-System-mailer Alternative Proposal for class updating
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 15 Jan 88 14:20:56 PST
Received: from Cabernet.ms by ArpaGateway.ms ; 15 JAN 88 14:21:05 PST
Date: 15 Jan 88 14:17 PST
From: Bobrow.pa@Xerox.COM
Subject: Alternative Proposal for class updating
To: Common-Lisp-Object-System@Sail.stanford.edu
Message-ID: <880115-142105-6052@Xerox>
The follwoing is based on suggstions made at the meeting by Gabriel, Dussud and
Moon. It is still a sketch. If it seems about right I will send a more complete
writeup. It replaces the class specific generic functions
It replaces the . I want to consider the following as a replacement for
update-class, propagate-class-update, and update-class-locally with some general
mechanisms that have wider applicability. These include a facility for
reinitialization, a facility for recording dependents for a specific object, and
a protocol for updating those dependents.
The generic functions used are:
Reintialization:
reinitialize-instance (object &rest reinit-args)
This generic function is intended to initialize again the object. The default
method augments the given reinit-args using default-initargs, checks the
arguments, and calls initialize-instance. It then updates any dependents
method-keyword-arguments (generic-function list-of-arguments)
This generic function provides an facility to help users to write code for
checking legality of keyword arguments.
Recording dependencies.
add-dependent(object dependent &key)
remove-dependent(object dependent &key)
all-dependents(object)
These three generic functions allow the recording of dependencies. Nothing is
specified about what the dependencies are.
The real work is done here:
update-dependent(object dependent &key)
-----
Here are some sketches of methods:
(defmethod reinitialize-instance
((object standard-object) &rest reinit-args)
(let*((arglist (list object)
(acceptable-args
(union
(method-keyword-arguments #'initialize-instance arglist)
(method-keyword-arguments #'reinitialize-instance arglist)
(class-all-slot-initargs (class-of object)))))
;;; check the keyword arguments
(loop (key in reinit-args by cddr)
(or (member key acceptable-args) (error ...))
;;; now initialize the instance
(apply #'initialize-instance
object
(default-init-args object reinit-args)
;;; update all dependents
(loop (dep in (all-dependents object))
(apply #'update-dependent object dependent reinit-args))
object)
(defmethod update-dependent
((class standard-class) (dependent standard-class)
&key direct-superclasses direct-slots direct-options)
;;; mark-inheritance as unfinalized,
;;; potentially make-instances-obsolete.)
(defmethod finalize-inheritance ((class standard-class))
;;; compute-cpl
;;; compute-slots
;;; add us as dependent to all classes on
;;; class-precedence-list. Note that this includes us.
;;; mark as finalized.)
(defmethod reinitialize-instance :before
((class standard-class)
&key direct-superclasses direct-slots direct-options)
;;; unhook old direct-subclass pointers and add new ones
;;; undefine old accessors that are no longer needed)
∂15-Jan-88 2050 Common-Lisp-Object-System-mailer DEFMETHOD Specification
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 15 Jan 88 20:50:39 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 322130; Fri 15-Jan-88 23:41:53 EST
Date: Fri, 15 Jan 88 23:41 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: DEFMETHOD Specification
To: Patrick H Dussud <DUSSUD@jenner.csc.ti.com>
cc: Common-Lisp-Object-System@SAIL.STANFORD.EDU
In-Reply-To: <2778251512-2385869@Jenner>
Message-ID: <19880116044142.5.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Fri, 15 Jan 88 10:31:52 CST
From: Patrick H Dussud <DUSSUD@jenner.csc.ti.com>
If the DEFMETHOD spec, in the second paragraph [ If (fboundp function-specifier) is
nil], it says that the lambda-list of the [created] generic function is congruent
with the lambda-list of the method. This is not specific enough, given our rules
on lambda-list congruence.
The issue is:
If the method lambda-list contains some keys, do we create the generic function
lambda-list with these keys present? If we do, then we enforce the fact that every
method for this generic function must accept these keys.
I think that we shouldn't put them in the generic function lambda-list, but either
way, this needs to be specified.
Good point. The generic function lambda-list should have &key with no
parameter specifiers after it in this case. The document should say this
explicitly.
∂18-Jan-88 1803 Common-Lisp-Object-System-mailer add-method
To: common-lisp-object-system@SAIL.Stanford.EDU
From: Linda DeMichiel <LGD@SAIL.Stanford.EDU>
Now that we've moved (make-instance 'standard-method ...) to the
meta-object protocol chapter, I'd like to suggest that we move
add-method there as well. add-method no longer seems to belong in
with the programmer interface functions, since there is no longer a
programmer interface level way of creating its second argument (a
method object). (The only way one can currently get one's hands on
a method object using the programmer interface level functions is
to call get-method on another generic function, or, of course, to
call defmethod).
-lgd
∂19-Jan-88 0213 Common-Lisp-Object-System-mailer Object Lisp vs CLOS in BYTE (Jan 88)
Received: from labrea.Stanford.EDU by SAIL.Stanford.EDU with TCP; 19 Jan 88 02:13:36 PST
Received: by labrea.Stanford.EDU; Tue, 19 Jan 88 02:13:35 PST
Received: from bhopal.lucid.com by edsel id AA08727g; Tue, 19 Jan 88 02:07:03 PST
Received: by bhopal id AA13774g; Tue, 19 Jan 88 02:10:16 PST
Date: Tue, 19 Jan 88 02:10:16 PST
From: Jon L White <edsel!jonl@labrea.Stanford.EDU>
Message-Id: <8801191010.AA13774@bhopal.lucid.com>
To: labrea!Common-Lisp-Object-System%Sail@labrea.Stanford.EDU
Subject: Object Lisp vs CLOS in BYTE (Jan 88)
In the current issue of BYTE magazine, there is a review of Allegro
Common Lisp [the Coral/Franz collusion for the MacIntosh].
Although the reviewer isn't a Lisp Wizard (he says things like "The
compiler uses tail recursion to minimize stack space." where he
probably should have said "tail recursion elimination"), still he seems
to have the knowledge level of an AI user. He goes on at length about
how the CLOS specification isn't complete yet, and how Object LISP is
offered instead. He knows enough to compare CLOS with "Xerox CommonLoops"
and Symbolics "New Flavors".
But he praises Object LISP to a large degree:
"However, Object LISP is an interesting way to implement objects
in Common LISP. I particularly like the way it places classes
and instances on the same level. It has always seemed artificial
to be able to create objects only as instances of already existing
classes. . . .
I would like Object LISP to be included with Allegro CL wven when
CLOS becomes available. . . ."
This looks like a case for cleaning up the documentation relating
CLOS to "delagation" type systems.
-- JonL --
∂19-Jan-88 0846 Common-Lisp-Object-System-mailer some questions on your chapter 2 comments
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 19 Jan 88 08:45:55 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 323377; Tue 19-Jan-88 11:45:23 EST
Date: Tue, 19 Jan 88 11:45 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: some questions on your chapter 2 comments
To: Linda DeMichiel <LGD@SAIL.STANFORD.EDU>
cc: Common-Lisp-Object-System@SAIL.STANFORD.EDU
In-Reply-To: The message of 18 Jan 88 21:08 EST from Linda DeMichiel <LGD@SAIL.Stanford.EDU>
Message-ID: <19880119164517.8.MOON@EUPHRATES.SCRC.Symbolics.COM>
[Added back the rest of the mailing list for this question, which is
of general interest.]
Date: 18 Jan 88 1808 PST
From: Linda DeMichiel <LGD@SAIL.Stanford.EDU>
In your comments on chapter 2 you mention:
2-29 first line: This says that removing a :method from a defgeneric and
re-evaluating the defgeneric does not remove the old method. While that's
a good default behavior, we should make sure not to rule out smart program
development environments that know better what is going on and remove the
old method in cases where the user thinks that's appropriate. In the Error
Terminology introduced in chapter 1, implementations should be free to
extend this. Redefinition is a program development environment issue, not
really a language issue, anyway.
This suggested change doesn't sound right to me. The problem is that
if this behavior on the part of defgeneric is extensible, programs
that rely on the "default" behavior from defgeneric won't be portable.
Or did you intend something else here?
Redefining a definition is a program development operation, not a programming
language operation. Portable programs, with the possible exception of portable
program development tools, wouldn't depend on what happens when a defgeneric is
evaluated twice.
It wouldn't bother me a bit if we changed the language to require all
implementations to remove methods that were created by a defgeneric, if
the defgeneric were re-evaluated without the :method. We already do this
for accessor methods created by defclass. We're now saying that the class
remembers the specific method objects and removes them if they are still
there; if they've already been replaced by a defmethod, it doesn't remove
the method put there by the defmethod.
What would bother me would be if we required all implementations to be
stupid about this.
So how about it? Shall we change CLOS so that re-evaluating a defgeneric
removes methods that were previously defined by :method, but no longer
appear in the new defgeneric form? I think we should.
∂19-Jan-88 0939 Common-Lisp-Object-System-mailer Re: some questions on your chapter 2 comments
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 19 Jan 88 09:39:02 PST
Received: from Cabernet.ms by ArpaGateway.ms ; 19 JAN 88 09:38:14 PST
Date: 19 Jan 88 09:37 PST
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Re: some questions on your chapter 2 comments
In-reply-to: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>'s message of
Tue, 19 Jan 88 11:45 EST
To: Moon@STONY-BROOK.SCRC.Symbolics.COM
cc: LGD@SAIL.STANFORD.EDU, Common-Lisp-Object-System@SAIL.STANFORD.EDU
Message-ID: <880119-093814-1652@Xerox>
So how about it? Shall we change CLOS so that re-evaluating a
defgeneric removes methods that were previously defined by :method,
but no longer appear in the new defgeneric form? I think we should.
I think that's a good idea. Should we specify how defgeneric knows that a
method was defined by :method. We could use a predicate or we could make
:method specified methods be a subclass of defgeneric-method. This similar to
how accessors methods are specified, and is what I reecommend.
∂19-Jan-88 1255 Common-Lisp-Object-System-mailer Re: some questions on your chapter 2 comments
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 19 Jan 88 12:49:55 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 323580; Tue 19-Jan-88 14:51:57 EST
Date: Tue, 19 Jan 88 14:51 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: some questions on your chapter 2 comments
To: Common-Lisp-Object-System@SAIL.STANFORD.EDU
In-Reply-To: <880119-093814-1652@Xerox>
Message-ID: <19880119195151.1.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: 19 Jan 88 09:37 PST
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
So how about it? Shall we change CLOS so that re-evaluating a
defgeneric removes methods that were previously defined by :method,
but no longer appear in the new defgeneric form? I think we should.
I think that's a good idea. Should we specify how defgeneric knows that a
method was defined by :method. We could use a predicate or we could make
:method specified methods be a subclass of defgeneric-method. This similar to
how accessors methods are specified, and is what I reecommend.
We decided at our last meeting that each class has a slot in which it
remembers a list of the defclass-defined methods. I'm not imagining this,
am I? I remember that idea winning out over giving each method a slot that
says how it was defined or having defclass-defined methods be a special
subclass.
I think defgeneric should handle its specially-defined methods in exactly
the same way that defclass handles its.
∂19-Jan-88 1317 Common-Lisp-Object-System-mailer Re: add-method
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 19 Jan 88 13:17:37 PST
Received: from Cabernet.ms by ArpaGateway.ms ; 19 JAN 88 13:16:18 PST
Date: 19 Jan 88 13:16 PST
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Re: add-method
In-reply-to: Linda DeMichiel <LGD@SAIL.Stanford.EDU>'s message of 18 Jan 88
18:03 PST
To: LGD@SAIL.Stanford.EDU
cc: common-lisp-object-system@SAIL.Stanford.EDU
Message-ID: <880119-131618-2133@Xerox>
Now that we've moved (make-instance 'standard-method ...) to
the meta-object protocol chapter, I'd like to suggest that we move
add-method there as well. add-method no longer seems to belong in
with the programmer interface functions, since there is no longer a
programmer interface level way of creating its second argument (a
method object). (The only way one can currently get one's hands on
a method object using the programmer interface level functions is
to call get-method on another generic function, or, of course, to
call defmethod).
Since there are ways of getting methods, and moving methods is a reasonable
thing to do, I think it is still reasonable to have add-method in chapter 2.
Didn't we agree that in the long run, there will only be two chapters - with
extensions to chapters 1 and 2.
∂19-Jan-88 1546 Common-Lisp-Object-System-mailer Re: some questions on your chapter 2 comments
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 19 Jan 88 15:46:08 PST
Received: from Cabernet.ms by ArpaGateway.ms ; 19 JAN 88 15:43:16 PST
Date: 19 Jan 88 15:40 PST
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Re: some questions on your chapter 2 comments
In-reply-to: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>'s message of
Tue, 19 Jan 88 14:51 EST
To: Moon@STONY-BROOK.SCRC.Symbolics.COM
cc: Common-Lisp-Object-System@SAIL.STANFORD.EDU
Message-ID: <880119-154316-2487@Xerox>
I think defgeneric should handle its specially-defined methods
in exactly the same way that defclass handles its.
I agree.
We decided at our last meeting that each class has a slot in
which it remembers a list of the defclass-defined methods. I'm not
imagining this, am I? I remember that idea winning out over giving
each method a slot that says how it was defined or having
defclass-defined methods be a special subclass.
I don't remember this, but my memory and notes are not to be trusted. Do you
remember any of the arguments for this decision. An argument against this is
that it implies that remove-method, and add-method that overrides must both be
cognizant of (side-effect) this list in this slot.
∂21-Jan-88 1130 Common-Lisp-Object-System-mailer METHOD-LAMBDA and Removing parsing
Received: from Score.Stanford.EDU by SAIL.Stanford.EDU with TCP; 21 Jan 88 11:25:25 PST
Received: from hplabs.HP.COM by SCORE.STANFORD.EDU with TCP; Thu 21 Jan 88 11:21:12-PST
Received: from hplms2.HP.COM (hplms2) by hplabs.HP.COM with SMTP ; Thu, 21 Jan 88 11:23:34 PST
Received: from hplabsz.hpl.hp.com (hplabsz.hpl.hp.com) by hplms2.HP.COM; Thu, 21 Jan 88 11:23:16 pst
Received: from hplabsz by hplabsz; Thu, 21 Jan 88 11:25:23 pst
To: Gregor.pa@Xerox.COM
Cc: common-lisp-object-system@sail.stanford.edu
Subject: METHOD-LAMBDA and Removing parsing
In-Reply-To: Your message of Fri, 15 Jan 88 13:11:00 -0800.
<880115131101.2.GREGOR@SPIFF.parc.xerox.com>
Date: Thu, 21 Jan 88 11:25:20 PST
Message-Id: <6211.569791520@hplabsz>
From: kempf%hplabsz@hplabs.HP.COM
I agree that the DEFMETHOD and DEFCLASS parsing stuff should be removed.
I'd like to see more on METHOD-LAMBDA and METHOD-APPLY before passing
judgement on their suitability, however.
jak
∂21-Jan-88 1132 Common-Lisp-Object-System-mailer Re: CALL-NEXT-METHOD and funcall-qua/send-as
Received: from Score.Stanford.EDU by SAIL.Stanford.EDU with TCP; 21 Jan 88 11:32:42 PST
Received: from hplabs.HP.COM by SCORE.STANFORD.EDU with TCP; Thu 21 Jan 88 11:28:20-PST
Received: from hplms2.HP.COM (hplms2) by hplabs.HP.COM with SMTP ; Thu, 21 Jan 88 11:30:45 PST
Received: from hplabsz.hpl.hp.com (hplabsz.hpl.hp.com) by hplms2.HP.COM; Thu, 21 Jan 88 11:30:25 pst
Received: from hplabsz by hplabsz; Thu, 21 Jan 88 11:32:29 pst
To: common-lisp-object-system@sail.stanford.edu
Subject: Re: CALL-NEXT-METHOD and funcall-qua/send-as
In-Reply-To: Your message of Tue, 12 Jan 88 22:08:44 -0800.
<8801130608.AA15662@bhopal.lucid.com>
Date: Thu, 21 Jan 88 11:32:26 PST
Message-Id: <6284.569791946@hplabsz>
From: kempf%hplabsz@hplabs.HP.COM
Sorry it's taken so long to reply. I've been out of town for two weeks.
In fact, the original question was one of exactly what the semantics
were for CALL-NEXT-METHOD with arguments. This came up when we
were modifying the algebraic specification for method combination to
include arguments. The precise question was whether the classes of
the actual parameters to CALL-NEXT-METHOD could be superclasses of
the actual parameters to the calling method (in which case a more
general method would be invoked) or whether they had to be exactly
the same (in which case only the next most general method would be
invoked). The reply which Danny and Dave gave was the latter. This
limits CALL-NEXT-METHOD with arguments to being able to supply different
actual parameter values to the next most general method, but, as Dave
pointed out, simplifies understanding of control flow.
I agree with Dave's point that this semantics is the simplist, and
thus probably the best.
jak
∂21-Jan-88 1428 Common-Lisp-Object-System-mailer Remarks
To: common-lisp-object-system@SAIL.Stanford.EDU
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>
Here are some remarks on the topics discussed recently. By the way,
there is a new CONCEP.TEX and CONCEP.DVI on SAIL.
These remarks treat the issues in reverse order to how they were
sent to the list:
I think defgeneric should handle its specially-defined methods
in exactly the same way that defclass handles its.
I'm not sure what the specially-defined methods might be for a defgeneric.
My reading of the specification states that if some method descriptions
are supplied some methods are defined, but none of those are specially
defined in the manner that they are using defclass - in the defclass case
I suppose the specialness is tied up with the fact that they are
implicitly defined, though at the behest of the :reader, :writer, or
:accessor options. I notice no other methods mentioned.
The model currently stated is clear - defgeneric is semantically equivalent
to an ensure-generic-function and a series of defmethod's. I see no obvious
parallel with defclass. With defclass, the ``specially-defined'' methods are
so defined according to a strong convention that we have imposed - we would
all be surprised to see people write simple defclass forms and then a
series of defmethod's to build up the readers and writers. But the
method-defining parts of defgeneric are form completeness only - we do
not advocate that people write method definitions within defgeneric forms.
If people do not like the fact that re-loading defgeneric forms doesn't
do what they want, then they can re-write them as simpler defgeneric's
and defmethod's, and they will be obeying classic object-oriented style
all the more if they do.
So I am against treating these methods in a manner analogous to
those defined by defclass.
On ADD-METHOD:
Since there are ways of getting methods, and moving methods is
a reasonable thing to do, I think it is still reasonable to
have add-method in chapter 2.
I know one can get methods, but I thought it was not possible to take a
method from one generic function and move it to another - that all one
could do is grab a method, grab its method function, make up a method
object from that, and then put that on a generic function. The step of
making the method object is achieved by make-instance of standard-method,
which is in chapter 3. Therefore, I believe it belongs in chapter 3.
Didn't we agree that in the long run, there will only be two
chapters - with extensions to chapters 1 and 2.
I think we agreed that in the long run this is desireable. We are currently
not trying to accomplish this merger, and I think it is reasonable to
to alter that to trying to not accomplish the merger. The point of this
is to make sure that the X3J13 troops can see what they get and don't get
if they think they don't like meta-object stuff. I'm sure that they
will desire inclusion of chapter 3, and at that point someone can
make the enormous effort to merge them. I think that it would be
easier for that person if they have a cleanly separated base level
and meta level to start with, especially if that is so easy to
accomplish right now. Remember, I want to go to the next meeting
with a chapter 1-2 package that stands alone and a chapter 3 package
that can be easily added.
I think that having such a separation can help our strategy at X3J13,
which would be to state that here is chapters 1 and 2 neatly wrapped
up as we promised, and all that needs to be really discussed is chapter
3. We can avoid unnecessary yapping by the hangers on that this
or that detail in chapter 1-2 is unpalatable, and we can have that
important chapter 3 discussion in which we sell it to them.
∂21-Jan-88 1609 Common-Lisp-Object-System-mailer Remarks
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 21 Jan 88 16:09:14 PST
Received: from Semillon.ms by ArpaGateway.ms ; 21 JAN 88 15:16:46 PST
Date: Thu, 21 Jan 88 15:15 PST
From: Gregor.pa@Xerox.COM
Subject: Remarks
To: Dick Gabriel <RPG@SAIL.STANFORD.EDU>
cc: common-lisp-object-system@SAIL.STANFORD.EDU
Fcc: BD:>Gregor>mail>outgoing-mail-1.text
In-Reply-To: The message of 21 Jan 88 14:28 PST from Dick Gabriel
<RPG@SAIL.Stanford.EDU>
Message-ID: <880121151504.9.GREGOR@SPIFF.parc.xerox.com>
Line-fold: no
Date: 21 Jan 88 14:28 PST
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>
On ADD-METHOD:
Since there are ways of getting methods, and moving methods is
a reasonable thing to do, I think it is still reasonable to
have add-method in chapter 2.
I know one can get methods, but I thought it was not possible to take a
method from one generic function and move it to another - that all one
could do is grab a method, grab its method function, make up a method
object from that, and then put that on a generic function. The step of
making the method object is achieved by make-instance of standard-method,
which is in chapter 3. Therefore, I believe it belongs in chapter 3.
I sort of agree except that there is a simple documented way to create a
method.
(get-method (generic-function (x)
(:method ((x position))
(with-slots (x y)
position
(incf x)
(incf y))))
()
(list (class-named 'position)))
Given that method, one could use remove-method and add-method to move it
around.
This example brings up an interesting question. Should CLtL specify a
way to compile a method function if it is not already compiled? Sure
one could do:
(setf (method-function (get-method ..))
(compile ni (method-function (get-method ..))))
but perhaps we should specify that compile with a method object as its
first (and only) argument compiles that methods function if it is
uncompiled. Compile with a method as its first argument and a lambda as
its second would compile and install the lambda?
-------
∂21-Jan-88 1646 Common-Lisp-Object-System-mailer ADD-METHOD
To: common-lisp-object-system@SAIL.Stanford.EDU
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>
I was under the impression that only freshly-created method objects could
be added to generic functions, and that in order to move an existing
method from one generic function to another required a step of
MAKE-INSTANCE using the method function. If that's not true, then
we ought to leave add-method in chapter 2.
There are several other simple documented ways to make methods, and I
thought of them all. It happens that all of them except MAKE-INSTANCE
install the method objects in generic functions.
-rpg-
∂21-Jan-88 1751 Common-Lisp-Object-System-mailer functi
To: common-lisp-object-system@SAIL.Stanford.EDU
From: Linda DeMichiel <LGD@SAIL.Stanford.EDU>
There is a new functi.tex and functi.dvi on sail.
-lgd
∂21-Jan-88 1844 Common-Lisp-Object-System-mailer Re: ADD-METHOD
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 21 Jan 88 18:44:28 PST
Received: from Cabernet.ms by ArpaGateway.ms ; 21 JAN 88 18:23:19 PST
Date: 21 Jan 88 18:23 PST
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Re: ADD-METHOD
In-reply-to: Dick Gabriel <RPG@SAIL.Stanford.EDU>'s message of 21 Jan 88 16:46
PST
To: RPG@SAIL.Stanford.EDU
cc: common-lisp-object-system@SAIL.Stanford.EDU
Message-ID: <880121-182319-1013@Xerox>
I was under the impression that only freshly-created method
objects could be added to generic functions, and that in order to
move an existing method from one generic function to another
required a step of MAKE-INSTANCE using the method function. If
that's not true, then we ought to leave add-method in chapter 2.
There are several other simple documented ways to make methods,
and I thought of them all. It happens that all of them except
MAKE-INSTANCE install the method objects in generic functions.
-rpg-
Methods removed from generic-functions are as naked as the day they were born.
∂22-Jan-88 1303 Common-Lisp-Object-System-mailer ADD-METHOD
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 22 Jan 88 13:02:28 PST
Received: from Semillon.ms by ArpaGateway.ms ; 22 JAN 88 12:56:34 PST
Date: Fri, 22 Jan 88 12:55 PST
From: Gregor.pa@Xerox.COM
Subject: ADD-METHOD
To: Dick Gabriel <RPG@SAIL.STANFORD.EDU>
cc: common-lisp-object-system@SAIL.STANFORD.EDU
Fcc: BD:>Gregor>mail>outgoing-mail-1.text
In-Reply-To: The message of 21 Jan 88 16:46 PST from Dick Gabriel
<RPG@SAIL.Stanford.EDU>
Message-ID: <880122125523.8.GREGOR@SPIFF.parc.xerox.com>
Line-fold: no
Date: 21 Jan 88 16:46 PST
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>
I was under the impression that only freshly-created method objects could
be added to generic functions, and that in order to move an existing
method from one generic function to another required a step of
MAKE-INSTANCE using the method function. If that's not true, then
we ought to leave add-method in chapter 2.
I believe that a method can only be on one generic function at a time,
but that it is perfectly alright to use add-method to add a method
somewhere once you have used remove-method to remove it from where it
used to be.
-------
∂23-Jan-88 0725 Common-Lisp-Object-System-mailer Re: New Class Organization for CLOS Kernel
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 23 Jan 88 07:25:45 PST
Received: from Cabernet.ms by ArpaGateway.ms ; 23 JAN 88 07:26:14 PST
Date: 23 Jan 88 07:25 PST
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Re: New Class Organization for CLOS Kernel
In-reply-to: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>'s message of
Mon, 28 Dec 87 15:51 EST
To: Moon@STONY-BROOK.SCRC.Symbolics.COM
cc: common-lisp-object-system@SAIL.STANFORD.EDU
Message-ID: <880123-072614-2701@Xerox>
Date: 23 Dec 87 14:34 PST From: Danny Bobrow
<Bobrow.pa@Xerox.COM>
The following is my understanding of what we agreed to in
Cambridge.
Date: Mon, 28 Dec 87 15:51 EST From: David A. Moon
<Moon@STONY-BROOK.SCRC.Symbolics.COM>
Agreed, except for some problems with the class relationships:
standard-accessor-method and standard-method should be disjoint
for the same reason that standard-class, built-in-class, and
structure-class are now disjoint.
I agree with the principle stated below. At first I disagreed with the
application of the principle to accessor methods based on Gregor's message, but
now I see it more as an open question. Here are some issues I see. Can one use
an accessor to change (or fetch) the method-function of an accessor? Is the
contract of an accessor to be effectively just a call to slot-value? Or can a
user insert a random function in an instance of type accessor method. If the
issue of method-function is the only difference, then won't a specialized method
on method-function and (setf method-function) do the trick. After all, these
accessors must combine in all the same ways that ordinary methods do, etc.
The principle underlying this is that we need to
distinguish between the class that is used by default
by the various macros, and the class from which other
classes inherit. This allows a programmer defining a new method to
choose whether this method is to be applicable to the default kind
of object that the macros make or to all objects (of the relevant
general kind). For example, standard-class is distinct from
structure-class, and they both inherit from class, so that a
programmer can put a method on standard-class to affect classes
made by defclass, or on class to affect all classes. Probably this
principle should be in your list of principles.
In thinking about this principle further I realized that we were missing from
the class lattice a type that allows us to distinguish objects whose metaclass
is structure-class. I propose that we include a class structure-object disjoint
from standard-object, that is a guaranteed superclass of all objects whose
metaclass is structure-class.
It's okay for standard-class-slot-description to be a subclass
of standard-slot-description, provided the idea is that
standard-class-slot-description is a kludge to avoid putting the
:allocation into a slot.
I now believe that it would be fine to have :allocation be part of the
standard-slot-description class. After our discussion in Cambridge, I think
that the value of a class slot is a joint association of the class and the slot,
not a property of the class-slot-description object. This allows us to
eliminate the class standard-class-slot-description.
Missing from the specification is
(class-slot-value class class-slot-name)
which returns the value associated with the class slot with name
<class-slot-name>. It signals an error if class-slot-name does not specify a
class-slot (inherited or direct) at the given class.
((Should this have gone in Chapter 2???))
Forward-referenced-class should be disjoint from standard-class
for the same reason, except that forward-referenced-class should
not exist at all,in my opinion.
In order to have a complete separation of the anonymous and named class
parts of the protocol, we need to convert names to classes before they
are stored as direct superclasses of a class. One way to avoid having
forward-referenced-class would be to use an instance of standard-class
that did not have its direct-superclasses or direct-slots specified,
such as one created by:
(make-instance 'standard-class)
Any attempt to use such a class in computing the class precedence list of a
subclass (a necessary prerequistite to making instances or defining methods)
would result in an error message of the form
"Attempt to use a class with no direct-superclasses specified"
giving the class name if the class had one. The advantage of using an
uninitialized standard-classes for a forward-referenced-class is that we need
this protection anyway. A disadvantage is that we would need to provide (if we
do not specify direct-superclasses as a slot) a predicate
initialized-direct-superclasses-p (class)
With instances of forward-referenced-class we could use a type test those
classes created by forward reference. Programming environment tools may want
special methods on forward-referenced-class for display in browsers etc that
would be more difficult to write the other way.
If we have forward-referenced-class, I agree it should be disjoint from
standard-class. I am undecided which of these alternatives I like better.
∂23-Jan-88 0810 Common-Lisp-Object-System-mailer Re: Class organization for CLOS kernel
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 23 Jan 88 08:10:49 PST
Received: from Cabernet.ms by ArpaGateway.ms ; 23 JAN 88 08:11:20 PST
Date: 23 Jan 88 08:10 PST
From: Bobrow.pa@Xerox.COM
Subject: Re: Class organization for CLOS kernel
In-reply-to: mcvax!delphi!chicca@uunet.UU.NET (M.R. Boscotrecase)'s message of
Thu, 21 Jan 88 13:00:36 +0100
To: mcvax!delphi!chicca@uunet.UU.NET
cc: Bobrow.pa@Xerox.COM, blue!chicca@uunet.UU.NET,
common-lisp-object-system@sail.stanford.edu
Message-ID: <880123-081120-2731@Xerox>
From: mcvax!delphi!chicca@uunet.UU.NET (M.R. Boscotrecase)
Date: Thu, 21 Jan 88 13:00:36 +0100
Hello! I work in the DELPHI team that is implementing CLOS on
the ObjVlisp model. In our architecture the class structure-class
is an instance of the class structure-metaclass and inherits from
the class built-in-class. The class structure-metaclass is
necessary in order to override the behavior of the class
built-in-class (its make-instance method that produce an error
message). What we have is the following
(defclass structure-metaclass (class) () (:metaclass class))
(defmethod make-instance ((class structure-metaclass) &rest
initargs) (...))
(defclass structure-class (built-in-metaclass class t)
(slotds conc-name constructors copier predicate include
print-function
type named initial-offset documentation)) (:metaclass
structure-metaclass))
(defmethod initialize-instance ((class structure-class) ..)
(..))
In the mail I read that structure-class is instance
of standard-class and I think this causes a bootstraping problem.
Can you explain me why you want it?
There are three disjoint metaclasses which represent the two old
ways of having structures in Common Lisp (built-in and structure) and
one for the new class structure. These metaclasses themselves are all
instances of standard-class. Thus we have (approximately):
(defclass built-in-class (class) ())
(defclass structure-class (class)
(slotds conc-name constructors copier predicate include
print-function type named initial-offset documentation))
(defclass standard-class (class)
(direct-slots direct-superclasses direct-class-options))
The class named "class" is a "taxonomic" class that serves to identify
the common type of all these We also have two other "taxonomic"
classes, standard-object and structure-object, that serve as holders of
default methods for instances generated by standard-class and
structure-class respectively. It is guaranteed by the system that any
instance of any class that is a standard-class has standard-object in
its class precedence list. Any class that is an instance of
structure-class will have structure-object in its class precedence
list.
The methods for making instances are:
(defmethod make-instance ((class built-in-class) &ret initargs)
(error "can't make a builtin class this way"))
(defmethod make-instance ((class structure-class) &rest initargs)
;;; do what it takes to make structures
;;; call initialize-instance on the structure)
(defmethod make-instance ((class standard-class) &rest initargs)
;;; do what it takes to make standard instances
;;; call initialize-instance on the object)
)
(defmethod initialize-instance
((object standard-object) &rest initargs) ...)
(defmethod initialize-instance
((object structure-object) &rest initargs) ...)
We do not see the need to have an extra level of metaclass
like your structure-metaclass. structure-class is not
a subclass of built-in-class.
If we have
(defclass x-y-point ()(x y)
(:metaclass structure-class))
then (make-instance 'x-y-point ...)
will invoke the method above on structure-class. The class
of structure-class will not be involved.
----
The following is the most current version of the CLOS class lattice.
Indentation is used to indicate subclass relationships. Class names
surround by <..> indicate classes used for type determination. In
general, these "taxonomic" classes are abstract classes in the sense
that they are not expected to be instantiated.
T (built-in-class)
<standard-structure>
<standard-object>
<generic-function>
standard-generic-function (funcallable-standard-class)
<method>
standard-method
standard-accessor-method
standard-reader-method
standard-writer-method
<method-combination>
standard-method-combination
simple-method-combination
<slot-description>
standard-slot-description
standard-structure-slot-description
<class>
built-in-class
structure-class
forward-referenced-class
standard-class
funcallable-standard-class
A link not shown in the diagram is the subclass link from
generic-function to function. We are also still discussing whether
standard-accessor-method should be a subclass of standard-method, or
only of method.
∂25-Jan-88 1349 Common-Lisp-Object-System-mailer Comments on latest draft documents
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 25 Jan 88 13:49:45 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 327422; Sun 24-Jan-88 22:22:19 EST
Date: Sun, 24 Jan 88 22:22 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Comments on latest draft documents
To: Common-Lisp-Object-System@SAIL.STANFORD.EDU
Message-ID: <19880125032225.6.MOON@EUPHRATES.SCRC.Symbolics.COM>
Jan 20, 1988 20:06 draft of chapter 1:
1-15: The first paragraph under "Initializng Newly-added Shared Slots" needs
to clarify that if there is no :initform, the shared slot remains unbound.
The remaining two paragraphs under that heading belong under the next heading.
1-17: The first bullet under "Extensions" refers to the new class being an
instance of the old class, which doesn't make sense. I think it meant to
say "the old metaclass."
1-27: The list of method-defining forms should include defclass (because
of the :reader, :writer, and :accessor slot-options).
1-28 first non-bullet paragraph: The reference to method defining forms
that create generic functions really only applies to those method defining
forms that are not also generic function defining forms. Perhaps you need
a term for these. They are defmethod and defclass.
1-28 last bullet: In the reference to "The form (eql form)", the first
use of the word "form" is incorrect, since this is not technically a form.
I'd prefer either "The list (eql form)" or "The parameter specializer name
(eql form)".
1-29 paragraph numbered "2": P sub 1,i is a parameter specializer, not a
parameter specializer name; in the same sentence, the word "denote" should
be "are", for the same reason.
1-30 first line: This incorrectly assumes qualifiers have to be symbols.
Elsewhere we have indicated that qualifiers are compared with EQUAL.
Thus this line should be changed to "3. The lists of qualifiers of both
methods are {\bf equal}."
1-30 after rule 6: The reference to method-defining forms creating generic
functions applies only to the ones that are not also generic function
defining forms.
1-37: The list of names of built-in method combination types should include
STANDARD, or else the text should say this is the list of the m-c types
described just above, rather than all of them. Probably the former is
better, since the next sentence mentions the semantics of STANDARD m-c.
1-37 last bullet second sentence: "applicable methods" should be
"applicable primary methods".
1-40 first bullet: I assume generic functions created by defclass
also have class standard-generic-function, so add defclass to this list.
1-43 third paragraph third sentence: Add "and is not defaulted by a more
specific class." At most one default initial value form will be evaluated
for a given initialization argument, the form supplied by the most specific
of the classes that supply them.
1-44 fourth bullet second sentence: I fin the phrase "and the values of
the remaining default value forms are ignored" to be misleading. I think
it would be better just to delete it. Otherwise the conflict of number (the
earlier portion of the sentence indicated just two default value forms were
being discussed) and the risk of the reader misinterpreting this to say that
the other default value form is not evaluated would have to be dealt with.
1-45 fourth bullet third sentence: "less specific primary method" is a
typo for "more specific primary method".
Jan 21, 1988 17:39 draft of Chapter 2:
2-17 class-name: The name of a class should not be restricted in type. The
method signature should specialize new-value with t, the arguments should
say new-value is typically a symbol, and the semicolon clause under
values should be deleted. While a class's proper name is a symbol
unless symbol-class is somehow extended, class-name should be allowed
to be any object. One proposed extension we discussed earlier has
class-name a list of classes.
2-18 class-of remarks: If we're going to cross-reference figure 1-1, we
have to point out that class-of does not necessarily return the classes
listed there. It could return an implementation-dependent subclass.
However, we are adding a restriction beyond Common Lisp's TYPE-OF, because
for members of the classes in 1-1, it is not permitted for CLASS-OF to
return a superclass of the class listed. It might be worth pointing that
out explicitly here; to deduce this from what is already documented the
reader would need to know that generic function to method dispatching calls
CLASS-OF.
2-41 documentation method signatures: The parameter specializer name
for new-value should be t, not string. CLtL doesn't say anywhere what
values are allowed, but a reasonable inference is that NIL is allowed,
and "documentation information" might have been meant to include some
sort of structures as well. The allowable types here are a matter for
CL to define, not for CLOS to legislate.
2-52 initialize-instance method signature: &key &allow-other-keys can't be
right for the method; this would prevent check-initargs from doing
anything. It should be &rest initargs. Note that &key &allow-other-keys
-is- correct for the generic function (the syntax field).
2-81 with-added-methods remarks: The second paragraph and the two bullets
that follow it are slightly garbled. I believe this means to say what
happens when with-added-methods does -not- specify an option (the value
in the existing generic function is retained, rather than defaulting to
the default that efgeneric would use), however it doesn't say that. What
it does say doesn't really make sense, because it speaks of option
inheritance and then says how the options of the existing generic function
are all replaced.
That's it for now, but a small number of additional comments will follow,
tomorrow.
∂25-Jan-88 1648 Common-Lisp-Object-System-mailer Alternative Proposal for class updating
Received: from RELAY.CS.NET by SAIL.Stanford.EDU with TCP; 25 Jan 88 16:48:39 PST
Received: from relay2.cs.net by RELAY.CS.NET id ae18896; 25 Jan 88 17:34 EST
Received: from csc.ti.com by RELAY.CS.NET id ah07944; 25 Jan 88 17:10 EST
Received: from dsg by tilde id AA28636; Mon, 25 Jan 88 15:56:06 CST
Received: From Jenner By dsg Via CHAOS-NET With CHAOS-MAIL; Mon, 25 Jan 88 10:39:50 CST
Message-Id: <2779115850-485522@Jenner>
Date: Mon, 25 Jan 88 10:37:30 CST
From: Patrick H Dussud <DUSSUD@jenner.csc.ti.com>
To: Common-Lisp-Object-System@SAIL.STANFORD.EDU
Subject: Alternative Proposal for class updating
In-Reply-To: Msg of 15 Jan 88 14:17 PST from Bobrow.pa@xerox.com
The generic functions used are:
Reintialization:
reinitialize-instance (object &rest reinit-args)
This generic function is intended to initialize again the object. The default
method augments the given reinit-args using default-initargs, checks the
arguments, and calls initialize-instance. It then updates any dependents
I like the concept. I would like it to be more parallel to make-instance
though. reinitialize-instance could accept allocate-instance keywords as
well. We can imagine cases where we would want to reallocate the
instance, i.e update the instance allocation characteristics without
affecting the slots. We could re-use the MAKE-INSTANCE model:
(defmethod reinitialize-instance ((object standard-object) &rest reinitargs)
(setq reinitargs (default-initargs (class-of object) reinitargs))
(check-initargs (class-of object) reinitargs)
(apply #'reallocate-instance (class-of object ) reinitargs)
(apply #'intialize-instance object reinitargs))
We also have to tell what happens if a slot is unbound. Do we
reinitialize it to its initform when there is no reinitargs to
reinitialize it?
method-keyword-arguments (generic-function list-of-arguments)
This generic function provides an facility to help users to write code for
checking legality of keyword arguments.
Maybe this facility is not necessary for reinitialize-instance?
Recording dependencies.
add-dependent(object dependent &key)
remove-dependent(object dependent &key)
all-dependents(object)
These three generic functions allow the recording of dependencies. Nothing is
specified about what the dependencies are.
The real work is done here:
update-dependent(object dependent &key)
Here again, I like the concept. What bothers me is that update-dependent
is not called by make-instance but is called by reinitialize-instance. I
wonder if update-dependent shouldn't be called outside of
reinitialize-instance.
Patrick.
∂25-Jan-88 1918 Common-Lisp-Object-System-mailer Type-checking of slot values
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 25 Jan 88 19:17:57 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 328290; Mon 25-Jan-88 22:18:06 EST
Date: Mon, 25 Jan 88 22:18 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Type-checking of slot values
To: Common-Lisp-Object-System@SAIL.STANFORD.EDU
Message-ID: <19880126031814.6.MOON@EUPHRATES.SCRC.Symbolics.COM>
Reference: pages 1-13 and 2-23 of 20 Jan 88 draft.
CLtL p.158, p.310, p.6.
Sometime between August and November the definition of the :type
slot option was changed from "An implementation may or may not
choose to check the type of the new value when initializing or
assigning to a slot" to "An implementation is required to check
the type of the value being stored in a slot only under the safest
compiler safety setting and in the interpreter." I don't think
this change was every publically discussed.
Perhaps this is my bias that type declarations are only a crutch for
crippled machines showing, but I don't think this change was
appropriate. It is not consistent with CLtL's definition of the
:type slot option in defstruct and the type declaration for variables.
Violation of these type constraints "is an error."
It's perfectly legitimate to argue against the current definition of
type declarations in Common Lisp. I have no problem with that.
However, I don't think it's appropriate for this issue to be decided
by CLOS rather than by CL, nor do I think it a good idea for type
declarations in CLOS to have different semantics from type declarations
in the rest of CL.
I feel the definition of CLOS's :type slot-option must be changed back,
unless there is an agreed upon change to Common Lisp to accompany it.
∂26-Jan-88 0137 Common-Lisp-Object-System-mailer Type-checking of slot values
Received: from labrea.Stanford.EDU by SAIL.Stanford.EDU with TCP; 26 Jan 88 01:37:33 PST
Received: by labrea.Stanford.EDU; Tue, 26 Jan 88 01:37:46 PST
Received: from bhopal.lucid.com by edsel id AA11428g; Tue, 26 Jan 88 01:25:03 PST
Received: by bhopal id AA18453g; Tue, 26 Jan 88 01:28:37 PST
Date: Tue, 26 Jan 88 01:28:37 PST
From: Jon L White <edsel!jonl@labrea.Stanford.EDU>
Message-Id: <8801260928.AA18453@bhopal.lucid.com>
To: labrea!Moon%STONY-BROOK.SCRC.Symbolics.COM@labrea.Stanford.EDU
Cc: labrea!Common-Lisp-Object-System%SAIL.STANFORD.EDU@labrea.Stanford.EDU
In-Reply-To: David A. Moon's message of Mon, 25 Jan 88 22:18 EST <19880126031814.6.MOON@EUPHRATES.SCRC.Symbolics.COM>
Subject: Type-checking of slot values
The two sentences you are comparing here aren't really that different:
(1) "An implementation may or may not choose to check the type of the
new value when initializing or assigning to a slot"
(2) "An implementation is required to check the type of the value being
stored in a slot only under the safest compiler safety setting and
in the interpreter."
As I read these two, they require absolutely nothing in the way of error
checking.
The second one seems to be trying to constrain future requirements; that is,
the requirement for type checking will never be more strict than requireing
it at the most strict compiler safety settings. That certainly doesn't say
that an implementation can't do it at other compiler settings, nor does it
even imply that an implementation has to provide "compiler safety settings".
Further, it doesn't introduce any inconsistency with Common Lisp semantics of
variable declarations [because both wordings, at present, require nothing].
I vaguely remember this issue being thrashed out on CLOS mailing list just
after there was a round of complaints on the general common-lisp mailing
list about the loopholes in CLtL's frequent phrase "it is an error". If
anything, there seemed to be consensus *not* to leave CLOS so underspecified
that any old tune could be played on its fiddle. The alternative of requiring
safety checking on every slot initialization or updating is clearly
incompatible with the pages of CLtL you cite (p.310, p.158 and p.6), and with
the performance goals of a majority of Common Lisp vendors.
[I know Dick had a strong interest in seeing this loophole plugged up; he is
out of town now and may not be able to give his views for a few days -- I'm
sorry if I've not remembered his "side" of it correctly].
Now, concerning your apology for carping presumably about the phrase "safest
compiler safety setting":
Perhaps this is my bias that type declarations are only a crutch for
crippled machines showing . . .
There is a whole world out there that firmly *believes* in structured,
strongly-typed programming. The roots of their beliefs have nothing at all
to do with machine architectures, crippled or otherwise. Of course, some
would say that their philosophy makes better performance *possible* on
standard ("stock") hardware, but that really isn't the whole issue. The
question for us really is whether or not Common Lisp will acknowledge and
accept some of this "strongly typed" technology, and put it to good work in
a fruitful way.
If CLOS is defined is such a way that acceptable performance is only
achievable on "special purpose" hardware [e.g., a defclass is far too
slow to be a substitute for defstruct], then I suspect it will be subject
to Deutsch's Dictum:
"Any computer language that runs on only one manufacturer's
hardware is doomed to failure . . .
--- unless that manufacturer is IBM."
[Quotation of opinion given by L. Peter Deutsch in public forums during 1983
and 1984].
-- JonL --
∂26-Jan-88 0832 Common-Lisp-Object-System-mailer Type-checking of slot values
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 26 Jan 88 08:32:00 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 328522; Tue 26-Jan-88 11:31:33 EST
Date: Tue, 26 Jan 88 11:31 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Type-checking of slot values
To: Jon L White <edsel!jonl@labrea.Stanford.EDU>
cc: Common-Lisp-Object-System@SAIL.STANFORD.EDU
In-Reply-To: <8801260928.AA18453@bhopal.lucid.com>
Message-ID: <19880126163134.3.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Tue, 26 Jan 88 01:28:37 PST
From: Jon L White <edsel!jonl@labrea.Stanford.EDU>
The two sentences you are comparing here aren't really that different:
(1) "An implementation may or may not choose to check the type of the
new value when initializing or assigning to a slot"
(2) "An implementation is required to check the type of the value being
stored in a slot only under the safest compiler safety setting and
in the interpreter."
As I read these two, they require absolutely nothing in the way of error
checking.
If you read CLOS pages 1-6 and 2-23, that is clearly not the case. The
second one requires every implementation to signal an error in certain
circumstances.
...nor does it
even imply that an implementation has to provide "compiler safety settings".
CLtL page 160.
I'd rather not get into a discussion on this mailing list of whether
Lisp should or should not be changed into a strongly-typed language. That
belongs on some other list.
∂26-Jan-88 0848 Common-Lisp-Object-System-mailer Re: Type-checking of slot values
Received: from RELAY.CS.NET by SAIL.Stanford.EDU with TCP; 26 Jan 88 08:47:57 PST
Received: from relay2.cs.net by RELAY.CS.NET id ac01417; 26 Jan 88 11:22 EST
Received: from csc.ti.com by RELAY.CS.NET id ac13544; 26 Jan 88 11:10 EST
Received: from Jenner by tilde id AA13180; Tue, 26 Jan 88 08:46:52 CST
Message-Id: <2779195539-5273381@Jenner>
Date: Tue, 26 Jan 88 08:45:39 CST
From: Patrick H Dussud <DUSSUD@jenner.csc.ti.com>
To: "David A. Moon" <Moon@SCRC-STONY-BROOK.ARPA>
Cc: Common-Lisp-Object-System@SAIL.STANFORD.EDU
Subject: Re: Type-checking of slot values
In-Reply-To: Msg of Mon, 25 Jan 88 22:18 EST from "David A. Moon" <Moon@scrc-stony-brook.arpa>
In-Reply-To: Msg of Tue, 26 Jan 88 01:28:37 PST from Jon L White <edsel!jonl@labrea.stanford.edu>
Date: Mon, 25 Jan 88 22:18 EST
From: "David A. Moon" <Moon@scrc-stony-brook.arpa>
Subject: Type-checking of slot values
Reference: pages 1-13 and 2-23 of 20 Jan 88 draft.
CLtL p.158, p.310, p.6.
Sometime between August and November the definition of the :type
slot option was changed from "An implementation may or may not
choose to check the type of the new value when initializing or
assigning to a slot" to "An implementation is required to check
the type of the value being stored in a slot only under the safest
compiler safety setting and in the interpreter." I don't think
this change was every publically discussed.
I don't remember such discussion.
It's perfectly legitimate to argue against the current definition of
type declarations in Common Lisp. I have no problem with that.
However, I don't think it's appropriate for this issue to be decided
by CLOS rather than by CL, nor do I think it a good idea for type
declarations in CLOS to have different semantics from type declarations
in the rest of CL.
I feel the definition of CLOS's :type slot-option must be changed back,
unless there is an agreed upon change to Common Lisp to accompany it.
I agree.
Date: Tue, 26 Jan 88 01:28:37 PST
From: Jon L White <edsel!jonl@labrea.stanford.edu>
Subject: Type-checking of slot values
The two sentences you are comparing here aren't really that different:
(1) "An implementation may or may not choose to check the type of the
new value when initializing or assigning to a slot"
(2) "An implementation is required to check the type of the value being
stored in a slot only under the safest compiler safety setting and
in the interpreter."
As I read these two, they require absolutely nothing in the way of error
checking.
If I read (2), a type check is required when the SAFETY compiler switch
is set to 3. No such thing is said in (1).
I vaguely remember this issue being thrashed out on CLOS mailing list just
after there was a round of complaints on the general common-lisp mailing
list about the loopholes in CLtL's frequent phrase "it is an error". If
anything, there seemed to be consensus *not* to leave CLOS so underspecified
that any old tune could be played on its fiddle. The alternative of requiring
safety checking on every slot initialization or updating is clearly
incompatible with the pages of CLtL you cite (p.310, p.158 and p.6), and with
the performance goals of a majority of Common Lisp vendors.
I believe that (1) is close to what CLtL says (p. 158), agrees with
CLtL type declaration semantics, and is quite specific about it.
Now, concerning your apology for carping presumably about the phrase "safest
compiler safety setting":
Perhaps this is my bias that type declarations are only a crutch for
crippled machines showing . . .
There is a whole world out there that firmly *believes* in structured,
strongly-typed programming. The roots of their beliefs have nothing at all
to do with machine architectures, crippled or otherwise. Of course, some
would say that their philosophy makes better performance *possible* on
standard ("stock") hardware, but that really isn't the whole issue. The
question for us really is whether or not Common Lisp will acknowledge and
accept some of this "strongly typed" technology, and put it to good work in
a fruitful way.
I don't think that it is up to us [CLOS working group] to decide this.
If CLOS is defined is such a way that acceptable performance is only
achievable on "special purpose" hardware [e.g., a defclass is far too
slow to be a substitute for defstruct], then I suspect it will be subject
to Deutsch's Dictum:
I don't think that the type checking has anything to do with good
performance. The important thing for good performance is that an
implementation can optimize slot access based on :type information. I
don't want to take that away from CLOS, or CLtL.
Patrick.
∂26-Jan-88 1335 Common-Lisp-Object-System-mailer Re: Type-checking of slot values
Received: from Score.Stanford.EDU by SAIL.Stanford.EDU with TCP; 26 Jan 88 13:35:50 PST
Received: from hplabs.HP.COM by SCORE.STANFORD.EDU with TCP; Tue 26 Jan 88 13:26:01-PST
Received: from hplms2.HP.COM (hplms2) by hplabs.HP.COM with SMTP ; Tue, 26 Jan 88 13:28:43 PST
Received: from hplabsz.hpl.hp.com (hplabsz.hpl.hp.com) by hplms2.HP.COM; Tue, 26 Jan 88 13:28:21 pst
Received: from hplabsz by hplabsz; Tue, 26 Jan 88 13:30:27 pst
To: Patrick H Dussud <DUSSUD@jenner.csc.ti.com>
Cc: common-lisp-object-system@sail.stanford.edu
Subject: Re: Type-checking of slot values
In-Reply-To: Your message of Tue, 26 Jan 88 08:45:39 -0600.
<2779195539-5273381@Jenner>
Date: Tue, 26 Jan 88 13:30:23 PST
Message-Id: <14255.570231023@hplabsz>
From: kempf%hplabsz@hplabs.HP.COM
>
> If CLOS is defined is such a way that acceptable performance is only
> achievable on "special purpose" hardware [e.g., a defclass is far too
> slow to be a substitute for defstruct], then I suspect it will be subject
> to Deutsch's Dictum:
> I don't think that the type checking has anything to do with good
> performance. The important thing for good performance is that an
> implementation an optimize slot access based on :type information. I
> don't want to take that away from CLOS, or CLtL.
Sorry, but I think you're wrong. On stock hardware, FIXNUM + is one
instruction, and a compiler which can deduce when to use it will always
win over one that can't. Similiarly, with CLOS, a compiler which
can substitute two memory references for a call to SLOT-VALUE will
win, modulo concerns about SAFETY. Type checking is important for
performance on stock hardware, unfortunately, Common Lisp is defined
such that type checking is completely optional, guaranteeing divergence
between what different vendors supply. Whether or not that should be
fixed is a different story, and, as has been pointed out, this is
not the place to discuss it.
jak
∂26-Jan-88 1344 Common-Lisp-Object-System-mailer Re: Type-checking of slot values
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 26 Jan 88 13:44:22 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 328911; Tue 26-Jan-88 16:44:31 EST
Date: Tue, 26 Jan 88 16:44 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: Type-checking of slot values
To: kempf%hplabsz@hplabs.HP.COM
cc: Patrick H Dussud <DUSSUD@jenner.csc.ti.com>, common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: <14255.570231023@hplabsz>
Message-ID: <19880126214430.9.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Tue, 26 Jan 88 13:30:23 PST
From: kempf%hplabsz@hplabs.HP.COM
>
> If CLOS is defined is such a way that acceptable performance is only
> achievable on "special purpose" hardware [e.g., a defclass is far too
> slow to be a substitute for defstruct], then I suspect it will be subject
> to Deutsch's Dictum:
> I don't think that the type checking has anything to do with good
> performance. The important thing for good performance is that an
> implementation an optimize slot access based on :type information. I
> don't want to take that away from CLOS, or CLtL.
Sorry, but I think you're wrong. On stock hardware, FIXNUM + is one
instruction, and a compiler which can deduce when to use it will always
win over one that can't.
What does this have to do with a requirement that a particular construct
shall signal an error in a particular circumstance?
I think you two are using the phrase "type checking" to mean two different
things.
Note how I resist the urge to point out that a certain vendor's
processor, which said vendor claims is the only stock hardware anyone
would ever want to use, and has in fact succeeded in convincing several
other corporations of the merits of that idea, has a Common Lisp +
instruction.
∂26-Jan-88 1438 Common-Lisp-Object-System-mailer Re: Type-checking of slot values
Received: from Score.Stanford.EDU by SAIL.Stanford.EDU with TCP; 26 Jan 88 14:38:25 PST
Received: from hplabs.HP.COM by SCORE.STANFORD.EDU with TCP; Tue 26 Jan 88 14:08:17-PST
Received: from hplms2.HP.COM (hplms2) by hplabs.HP.COM with SMTP ; Tue, 26 Jan 88 14:10:45 PST
Received: from hplabsz.hpl.hp.com (hplabsz.hpl.hp.com) by hplms2.HP.COM; Tue, 26 Jan 88 14:10:19 pst
Received: from hplabsz by hplabsz; Tue, 26 Jan 88 14:12:27 pst
To: "David A. Moon" <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Cc: common-lisp-object-system@sail.stanford.edu
Subject: Re: Type-checking of slot values
In-Reply-To: Your message of Tue, 26 Jan 88 16:44:00 -0500.
<19880126214430.9.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Tue, 26 Jan 88 14:12:23 PST
Message-Id: <15831.570233543@hplabsz>
From: kempf%hplabsz@hplabs.HP.COM
> > I don't think that the type checking has anything to do with good
> > performance. The important thing for good performance is that an
> > implementation an optimize slot access based on :type information. I
> > don't want to take that away from CLOS, or CLtL.
> Sorry, but I think you're wrong. On stock hardware, FIXNUM + is one
> instruction, and a compiler which can deduce when to use it will always
> win over one that can't.
> What does this have to do with a requirement that a particular construct
> shall signal an error in a particular circumstance?
Nothing, which is probably as good a reason as any to terminate the discussion.
> I think you two are using the phrase "type checking" to mean two different
> things.
Right: 1) to check for errors 2) to help optimize performance. The
current Common Lisp declaration framework can do 2), though the compiler
may have to be smarter in some cases (which could be simpilified by
adding some declarations). Since the Common Lisp specification makes
declarations optional, however, the results of declaring things may be
nonportable. I presume by "should CL become statically typed" is meant 1),
to which my feeling is no, but this is not the right place to discuss it.
> Note how I resist the urge to point out that a certain vendor's
> processor, which said vendor claims is the only stock hardware anyone
> would ever want to use, and has in fact succeeded in convincing several
> other corporations of the merits of that idea, has a Common Lisp +
> instruction.
I'll refrain from asking specifics [ :-) ], but I don't oppose the idea
of having instructions for high use operations like Common Lisp +.
I think the language design should make it possible to implement
with relative efficiency (at perhaps larger compilation cost) even on
architectures which are less enlightened, however.
jak
∂26-Jan-88 1809 Common-Lisp-Object-System-mailer Type-checking of slot values
Received: from labrea.Stanford.EDU by SAIL.Stanford.EDU with TCP; 26 Jan 88 18:08:58 PST
Received: by labrea.Stanford.EDU; Tue, 26 Jan 88 18:09:09 PST
Received: from bhopal.lucid.com by edsel id AA15378g; Tue, 26 Jan 88 17:49:07 PST
Received: by bhopal id AA23379g; Tue, 26 Jan 88 17:52:51 PST
Date: Tue, 26 Jan 88 17:52:51 PST
From: Jon L White <edsel!jonl@labrea.Stanford.EDU>
Message-Id: <8801270152.AA23379@bhopal.lucid.com>
To: labrea!Moon%STONY-BROOK.SCRC.Symbolics.COM@labrea.Stanford.EDU,
labrea!DUSSUD%jenner.csc.ti.com@labrea.Stanford.EDU
Cc: labrea!Common-Lisp-Object-System%SAIL.STANFORD.EDU@labrea.Stanford.EDU
In-Reply-To: David A. Moon's message of Tue, 26 Jan 88 11:31 EST <19880126163134.3.MOON@EUPHRATES.SCRC.Symbolics.COM>
Subject: Type-checking of slot values
Date: Tue, 26 Jan 88 11:31 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Date: Tue, 26 Jan 88 01:28:37 PST
From: Jon L White <edsel!jonl@labrea.Stanford.EDU>
The two sentences you are comparing here aren't really that different:
(1) "An implementation may or may not choose to check the type of the
new value when initializing or assigning to a slot"
(2) "An implementation is required to check the type of the value being
stored in a slot only under the safest compiler safety setting and
in the interpreter."
As I read these two, they require absolutely nothing in the way of error
checking.
If you read CLOS pages 1-6 and 2-23, that is clearly not the case. The
second one requires every implementation to signal an error in certain
circumstances.
Just what is it that you think is "clearly not the case"? The two
alternative specifications above were under discussion -- not error checking
in general -- and nothing I've seen so far changes the meaning of either of
those two sentences. In fact, CLOS pages 1-6 and 2-23 support exactly the
summary I proposed, but which you omitted from your excerpt of my message:
". . . to constrain future requirements; that is, the
requirement for type checking will never be more strict
than requireing it at the most strict compiler safety settings."
See also my comments below on Patrick's confusion betewen "if" and "only-if".
...nor does it even
imply that an implementation has to provide "compiler safety settings".
CLtL page 160.
Sorry, that page doesn't say that *any* declaration at all has to affect
the compiler's behaviour. [I suppose we could keep this discussion up if
someone wants to imagine yet more unspoken meanings for "provide", but I'll
gracely bow out now].
I'd rather not get into a discussion on this mailing list of whether
Lisp should or should not be changed into a strongly-typed language. That
belongs on some other list.
No one has ever suggested changeing Lisp into a strongly-typed language. We
can cut this discussion short by eliminating the bogeymen.
Date: Tue, 26 Jan 88 08:45:39 CST
From: Patrick H Dussud <DUSSUD@jenner.csc.ti.com>
Date: Tue, 26 Jan 88 01:28:37 PST
From: Jon L White <edsel!jonl@labrea.stanford.edu>
Subject: Type-checking of slot values
The two sentences you are comparing here aren't really that different:
(1) "An implementation may or may not choose to check the type of the
new value when initializing or assigning to a slot"
(2) "An implementation is required to check the type of the value being
stored in a slot only under the safest compiler safety setting and
in the interpreter."
If I read (2), a type check is required when the SAFETY compiler switch
is set to 3. No such thing is said in (1).
Not as I read it! The phrase "<foo> is required only when <bar>" is definitely
not equivalent to the phrase "<foo> is required whenever <bar>". Could
this variant reading of "only when" be the source of all our disagreement?
I don't think that the type checking has anything to do with good
performance. The important thing for good performance is that . . .
Patrick.
Unfortunately, "type checking" does have something to do with performance,
if you take the view of the structured programming folks. That view says
that *no* data access is permitted unless it is proven correct; it doesn't
forbid runtime checks, but it biases towards compile time checks. These
folks are particularly aghast at languages like C where you have virtually
no compile time type checking, and none at all a runtime. The phrase
"type checking" is a slogan that often differentiates these two camps.
There *appears* to be a runtime cost for runtime type checking, and this is
not just a Lisp issue [however, few special-purose machines for languages
like functional-programming ML, or for super-strongly-typed languages like
Mesa, seem to have been commercial successes]. CLtL permits implementations
to range anywhere between the extremes of "No access until proven correct"
and "Anything goes". Caveat Luser.
It would be inconsistent with this CL philosophy for CLOS to insert a bias,
or requirement, for the former more "costly" approach.
-- JonL --
P.S. Since Moon failed to resist carping about the SPARC, I'll fail to resist
making the following challenge:
"SPARC does not have a Common Lisp + instruction, nor does it have any
special-purpose hardware for Lisp. Neither does the 'other' RISC chip
that nobody knows about. I'll debate this issue anytime, anyplace."
[but hopefully, not here in the mails of CLOS].
∂26-Jan-88 1848 Common-Lisp-Object-System-mailer Re: Type-checking of slot values
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 26 Jan 88 18:48:41 PST
Received: from Cabernet.ms by ArpaGateway.ms ; 26 JAN 88 18:49:10 PST
Date: 26 Jan 88 18:48 PST
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Re: Type-checking of slot values
In-reply-to: Jon L White <edsel!jonl@labrea.Stanford.EDU>'s message of Tue, 26
Jan 88 17:52:51 PST
To: edsel!jonl@labrea.Stanford.EDU
cc: Common-Lisp-Object-System@SAIL.STANFORD.EDU
Message-ID: <880126-184910-2818@Xerox>
FROM JONL
" The two sentences you are comparing here aren't really that different:
(1) "An implementation may or may not choose to check the type of the
new value when initializing or assigning to a slot"
(2) "An implementation is required to check the type of the value being
stored in a slot only under the safest compiler safety setting and
in the interpreter."
If I read (2), a type check is required when the SAFETY compiler switch
is set to 3. No such thing is said in (1).
Not as I read it! The phrase "<foo> is required only when <bar>" is definitely
not equivalent to the phrase "<foo> is required whenever <bar>". Could
this variant reading of "only when" be the source of all our disagreement?"
I certainly misread it that way. If it said
An implementation is required to check the type of the value being
stored in a slot at most when under the safest compiler
safety setting and in the interpreter."
Then it would be saying the same thing. But why should one use the word require
if the intent is to not require, but allow under certain safetey conditions.
Would it be better to say:
(2) "An implementation is allowed to check the type of the value being
stored in a slot only under the safest compiler safety setting and
in the interpreter."
This would stop it from being checked at other times. What is the intent?
∂27-Jan-88 0318 Common-Lisp-Object-System-mailer Type-checking of slot values
Received: from labrea.Stanford.EDU by SAIL.Stanford.EDU with TCP; 27 Jan 88 03:18:03 PST
Received: by labrea.Stanford.EDU; Wed, 27 Jan 88 03:18:16 PST
Received: from bhopal.lucid.com by edsel id AA18439g; Wed, 27 Jan 88 02:56:18 PST
Received: by bhopal id AA25486g; Wed, 27 Jan 88 03:00:04 PST
Date: Wed, 27 Jan 88 03:00:04 PST
From: Jon L White <edsel!jonl@labrea.Stanford.EDU>
Message-Id: <8801271100.AA25486@bhopal.lucid.com>
To: labrea!Bobrow.pa%Xerox.COM@labrea.Stanford.EDU
Cc: labrea!Common-Lisp-Object-System%SAIL.STANFORD.EDU@labrea.Stanford.EDU
In-Reply-To: Danny Bobrow's message of 26 Jan 88 18:48 PST <880126-184910-2818@Xerox>
Subject: Type-checking of slot values
re: Would it be better to say:
(2) "An implementation is allowed to check the type of the value being
stored in a slot only under the safest compiler safety setting and
in the interpreter."
This would stop it from being checked at other times. What is the intent?
This may be the interpretation that Moon et al are objecting to; and I
wouldn't approve of it either. I certainly read the offending sentence
of CLOS 1-13
"<foo> is required only when <bar>"
as if it were
"<foo> is required at most when <bar>, and nothing is said
about the case of when not <bar>."
The intent of that paragraph is only to say that a slot value is permitted
to violate its corresponding :type specifier.
With respect to type-checking the slot values, there is clearer language
elsewhere in the CLOS documents; and it isn't nearly so ambiguous as CLtL's
universal excuse "it is an error". My preference as stated before is to
prohibit a rule *requiring* checking of slot values, except that under the
extremal safety settings such checking *may* be required. Note that this
phrasing grants permission for an implementation to do type-checking at all
safety levels, if it so chooses.
Incidentally, I would propose a benchmark of using defclass for defstruct,
and see if there is *any* mode where the user suffers no slowdown [:type
specifiers aren't the only hinderence to success here!]. Conversely, there
should be a test case that asks whether there is *any* mode where all slot
:type specifiers are always satisfied.
Linda thinks Dick put in the wording that Dave proposes to change; maybe
we should give him a chance to explain his intent.
-- JonL --
∂27-Jan-88 0934 Common-Lisp-Object-System-mailer Method Combination Objects
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 27 Jan 88 09:34:07 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 329494; Wed 27-Jan-88 12:34:17 EST
Date: Wed, 27 Jan 88 12:34 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Method Combination Objects
To: Common-Lisp-Object-System@SAIL.STANFORD.EDU
References: <19871229222722.4.MOON@EUPHRATES.SCRC.Symbolics.COM>,
<880113-103639-2495@Xerox>,
<19880115035749.6.MOON@EUPHRATES.SCRC.Symbolics.COM>,
<880115-135338-5966@Xerox>
Message-ID: <19880127173423.8.MOON@EUPHRATES.SCRC.Symbolics.COM>
There haven't been any dissenting comments, as I assume the design for
method combination meta objects agreed on by Danny and me is accepted
by everyone else.
First, the impact on chapters 1 and 2. Page numbers refer to the 20 Jan
1988 drafts.
1-33 last paragraph (excluding the implementation note), second sentence.
Replace this sentence with:
"The generic function {\bf compute-effective-method} receives as
arguments the generic function, the sorted list of applicable
methods, and the method combination instance."
Append to the paragraph:
"A method combination instance is a meta-object that encapsulates
the method combination type and options specified by the
{\bf :method-combination} option to forms that specify generic
function options."
1-40: This is optional, but I think we should add method combination
instances to the list of meta-objects. Each method combination instance
is an instance of a subclass of the class {\bf method-combination}.
I don't think we need to name any of the subclasses here, not even
{\bf standard-method-combination}; that's chapter 3 material for now.
2-42 documentation method signatures: Add two for method-combination
(italic) method-combination (bold), for documentation and for
setf of documentation. On the next page, under arguments, the first
bullet should mention method combination objects too.
2-43 ensure-generic-function arguments: Nothing really needs to be
changed, since the value of the :method-combination argument is not
described at all in the latest draft. However, I suggest two sentences
should be added:
"The {\bf :method-combination} argument is a method combination
instance. A method combination instance is a meta-object that
encapsulates the method combination type and options specified by the
{\bf :method-combination} option to forms that specify generic
function options."
That's all that has to be changed in chapters 1 and 2. Here's an
approximation of what goes into chapter 3. I have done no editing for
style here, only content. I've left out the design rationale this
time, to keep this small. Consult the referenced messages if you
want to see it again.
Method Combination Naming Layer
This layer is concerned with mapping method combination names and
options, as seen in the :method-combination option to defgeneric, to
method combination meta-objects.
(method-combination-instance generic-function
method-combination-name
method-combination-options)
=> method-combination
is how a method combination name and a list of options are converted
into an object. define-method-combination expands into a defmethod
for method-combination-instance. remove-method can be used to
undefine a method combination type.
method-combination-instance signals an error if
method-combination-name is unrecognized. Each method for
method-combination-instance signals an error if the
method-combination-options are unrecognized or there are
too many or too few of them.
method-combination-instance might return the same object each time
it is called with given arguments, or it might make a new object.
(method-combination-name method-combination) => symbol
(method-combination-options method-combination) => list
These two generic functions perform the inverse mapping.
Method Combination Object Layer
method-combination
This class is a superclass of all classes of method combination.
standard-method-combination
This class is the class of the method combination object used by default
when :method-combination is not specified.
Other implementation-dependent subclasses of method-combination exist.
For example, all invocations of the short form of
define-method-combination probably use one class, and each invocation of
the long form of define-method-combination probably defines a new class
which has a superclass in common with standard-method-combination.
CLOS does not specify how many of these classes there are nor what
their names are.
(compute-effective-method generic-function method-list method-combination)
=> effective-method-form
This generic function performs part 3 of the determination of the
effective method. define-method-combination works through methods that
specialize the third parameter.
(describe-method-concisely generic-function method method-combination)
This generic function prints a description of the method onto
*standard-output*. The value returned is ignored.
define-method-combination defines a method for describe-method-concisely
that uses the :description option of the long form to control
what it prints.
Other generic functions specialized by method combinations are not
currently defined by CLOS, but program development environments are
likely to have some.
A generic function object records a method combination object, rather
than the name and options of a method combination type. This changes
the initialization arguments and structural access functions for
generic functions from what is in chapter 3 now. defgeneric calls
method-combination-instance before it calls ensure-generic-function.
Example
The short form of define-method-combination could have been defined
as follows:
(defclass short-form-method-combination
(method-combination)
((name :initarg name :reader method-combination-name)
(order :initarg order)
(documentation :initarg documentation :reader documentation)
(operator :initarg operator)
(identity-with-one-argument :initarg identity-with-one-argument)))
(defmethod method-combination-options ((mc short-form-method-combination))
(list (slot-value mc 'order)))
(defmethod compute-effective-method (generic-function
methods
(mc short-form-method-combination))
(let ((primary-methods (remove (list (slot-value mc 'name))
methods :key #'method-qualifiers
:test-not #'equal))
(around-methods (remove '(:around)
methods :key #'method-qualifiers
:test-not #'equal)))
(when (eq (slot-value mc 'order) ':most-specific-last)
(setq primary-methods (reverse primary-methods)))
(dolist (method (set-difference methods
(union primary-methods around-methods)))
(invalid-method-error method "The qualifiers of ~S, ~:S, are not ~S or ~S"
method (method-qualifiers method)
(list (slot-value mc 'name)) '(:around)))
;;--- Note: this example has not been updated to reflect the removal
;;--- of make-method-call. If we do that, the update should be
;;--- straightforward.
(make-method-call `(,@around-methods
,(make-method-call primary-methods
:operator (slot-value mc 'operator)
:identity-with-one-argument
(slot-value mc 'identity-with-one-argument)))
:operator :call-next-method)))
(defmethod describe-method-concisely
(generic-function
method
(method-combination short-form-method-combination))
(declare (ignore generic-function))
(write-string (string-downcase (string (first (method-qualifiers method))))))
(defmacro define-method-combination
(name &key (documentation nil)
(operator name)
(identity-with-one-argument nil))
`(defmethod method-combination-instance
(generic-function
(name (eql ',name))
options)
(declare (ignore generic-function))
(apply #'(lambda (&optional (order ':most-specific-first))
(check-type order (member :most-specific-first
:most-specific-last))
(make-instance 'short-form-method-combination
'name ',name
'order order
'documentation ',documentation
'operator ',operator
'identity-with-one-argument
',identity-with-one-argument))
options)))
Example of Defining a Method Combination Type via Inheritance
;This example defines a method combination type that is similar
;to standard method combination, except that it also allows :or
;methods. The :or methods are executed after the :before methods,
;before the :after methods, inside the :around methods, and before
;the primary method. The primary method is only called if all the
;:or methods return nil; if any :or method returns non-nil, its
;value becomes the value of the generic function (or the value
;returned by call-next-method in the least specific :around method)
;in place of the values of the most specific primary method.
;This assumes approach 2 or 3 to making effective method code
;analyzable, and assumes one particular code analysis tool, whose
;details I will not try to explain here.
;Those assumptions are not critical.
;I'm assuming we don't want to try to extend the define-method-combination
;macro so that it could exploit inheritance. Instead I will
;define the example directly in terms of the next layer down.
(defclass standard-method-combination-with-or
(standard-method-combination)
())
(defmethod method-combination-instance
(generic-function
(name (eql 'standard-with-or))
options)
(declare (ignore generic-function))
(unless (null options)
(error "standard-with-or method combination does not accept options"))
(make-instance 'standard-method-combination-with-or))
;This uses call-next-method to get the effective method in the absence
;of any :or methods, then it modifies the effective method form to
;incorporate the :or methods in an OR special form wrapped around the
;call to the most specific primary method.
(defmethod compute-effective-method (generic-function
methods
(mc standard-method-combination-with-or))
(let ((or-methods (remove '(:or) methods :key #'method-qualifiers
:test-not #'equal))
(other-methods (remove '(:or) methods :key #'method-qualifiers
:test #'equal)))
(lt:copyforms #'(lambda (subform kind usage)
(declare (ignore usage))
(if (and (listp kind) (listp subform)
(eq (first subform) 'method-call)
(null (method-qualifiers (second subform))))
;; Put or methods before primary method
(values `(or ,@(mapcar #'(lambda (method)
`(method-call ,method))
or-methods)
,subform)
t)
;; Leave all other subforms of effective method alone
subform))
(call-next-method generic-function other-methods mc))))
∂27-Jan-88 1123 Common-Lisp-Object-System-mailer Method Combination Objects
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 27 Jan 88 11:23:45 PST
Received: from Semillon.ms by ArpaGateway.ms ; 27 JAN 88 11:19:26 PST
Date: Wed, 27 Jan 88 11:17 PST
From: Gregor.pa@Xerox.COM
Subject: Method Combination Objects
To: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
cc: Common-Lisp-Object-System@SAIL.STANFORD.EDU
Fcc: BD:>Gregor>mail>outgoing-mail-1.text
In-Reply-To: <19880127173423.8.MOON@EUPHRATES.SCRC.Symbolics.COM>
Message-ID: <880127111739.7.GREGOR@SPIFF.parc.xerox.com>
Line-fold: no
Date: Wed, 27 Jan 88 12:34 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
There haven't been any dissenting comments, as I assume the design for
method combination meta objects agreed on by Danny and me is accepted
by everyone else.
I have just a few problems with this. I have included only the parts of
your message I have problems with, all the other parts are just fine.
First off, I really don't like the name method-combination-instance. I
think it should be method-combination-object. I think the sentence "A
method combination instance is a meta object which..." shows why this
name is better. We call methods "method objects" and classes "class
objects" etc.
First, the impact on chapters 1 and 2. Page numbers refer to the 20 Jan
1988 drafts.
1-33 last paragraph (excluding the implementation note), second sentence.
Replace this sentence with:
"The generic function {\bf compute-effective-method} receives as
arguments the generic function, the sorted list of applicable
methods, and the method combination instance."
I would prefer the order of arguments:
(<generic-function> <method-combination-object> <methods>)
When its clear that only some arguments are intended to be specialized,
I like putting them up from. Also, those two arguments are the ones
that are going to consiper to work on the third so I like that order of
arguments for that reason too.
2-43 ensure-generic-function arguments: Nothing really needs to be
changed, since the value of the :method-combination argument is not
described at all in the latest draft. However, I suggest two sentences
should be added:
"The {\bf :method-combination} argument is a method combination
instance. A method combination instance is a meta-object that
encapsulates the method combination type and options specified by the
{\bf :method-combination} option to forms that specify generic
function options."
Method Combination Naming Layer
This layer is concerned with mapping method combination names and
options, as seen in the :method-combination option to defgeneric, to
method combination meta-objects.
(method-combination-instance generic-function
method-combination-name
method-combination-options)
=> method-combination
is how a method combination name and a list of options are converted
into an object. define-method-combination expands into a defmethod
for method-combination-instance. remove-method can be used to
undefine a method combination type.
method-combination-instance signals an error if
method-combination-name is unrecognized. Each method for
method-combination-instance signals an error if the
method-combination-options are unrecognized or there are
too many or too few of them.
method-combination-instance might return the same object each time
it is called with given arguments, or it might make a new object.
(method-combination-name method-combination) => symbol
(method-combination-options method-combination) => list
Since method-combination-instance (method-combination-object) must be
called before ensure-generic-function is called, its first argument is
actually a prototype of the generic function.
Also, are you proposing that once a generic function has a method
combination object it is not possible to extract that object from it?
What exactly happens with the :method-combination argument to ensure
generic function? It seems to me that argument should be stored away
`inside' the generic function and that it should be possible to extract
it and modify it. This would mean that there would be an accessor for
generic function called something like
generic-function-method-combination-object. It would also mean that
method-combination-object should return a new object each time and that
perhaps it should be called make-method-combination-object.
-------
∂27-Jan-88 1301 Common-Lisp-Object-System-mailer Method Combination Objects
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 27 Jan 88 13:01:47 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 329731; Wed 27-Jan-88 16:02:00 EST
Date: Wed, 27 Jan 88 16:01 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Method Combination Objects
To: Common-Lisp-Object-System@SAIL.STANFORD.EDU
In-Reply-To: <880127111739.7.GREGOR@SPIFF.parc.xerox.com>
Message-ID: <19880127210152.5.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Wed, 27 Jan 88 11:17 PST
From: Gregor.pa@Xerox.COM
Basically, I agree with all your suggestions. Details below.
Dick and/or Linda: if you want me to send out a revised version of what
I just sent out, with Gregor's suggestions incorporated, please let me
know. Otherwise I'll assume that you'll do the merging.
First off, I really don't like the name method-combination-instance. I
think it should be method-combination-object.
I agree. This doesn't affect chapter 1 or 2.
I would prefer the order of arguments: [for compute-effective-method]
(<generic-function> <method-combination-object> <methods>)
I agree. This affects chapter 1.
Since method-combination-instance (method-combination-object) must be
called before ensure-generic-function is called, its first argument is
actually a prototype of the generic function.
On 13 January, Danny said
[method-combination-instance] allows specialization on the class of
the generic function as well as on the name. Although useful, this
might not be important because compute-effective-method also allows
specialization on both the generic function and method combination
object.
Given this, and what you just pointed out, I think it was a mistake to make
the generic function an argument here. Thus I think the arguments should
be (method-combination-object name options) => object. This doesn't
affect chapter 1 or 2.
Also, are you proposing that once a generic function has a method
combination object it is not possible to extract that object from it?
What exactly happens with the :method-combination argument to ensure
generic function? It seems to me that argument should be stored away
`inside' the generic function and that it should be possible to extract
it and modify it. This would mean that there would be an accessor for
generic function called something like
generic-function-method-combination-object. It would also mean that
method-combination-object should return a new object each time and that
perhaps it should be called make-method-combination-object.
I agree with all this. I said somewhere in my message that the
existing chapter 3 accessors for generic function objects need to be
adjusted, but I didn't try to give any details since I don't have
access to the current version of chapter 3. Anything that returns the
method combination name or options, given a generic function, should
be removed, and something that returns the method combination object,
given a generic function, should be added. This doesn't affect
chapter 1 or 2.
∂27-Jan-88 1325 Common-Lisp-Object-System-mailer Re: Type-checking of slot values
Received: from Score.Stanford.EDU by SAIL.Stanford.EDU with TCP; 27 Jan 88 13:25:28 PST
Received: from hplabs.HP.COM by SCORE.STANFORD.EDU with TCP; Wed 27 Jan 88 13:20:41-PST
Received: from hplms2.HP.COM (hplms2) by hplabs.HP.COM with SMTP ; Wed, 27 Jan 88 13:23:34 PST
Received: from hplabsz.hpl.hp.com (hplabsz.hpl.hp.com) by hplms2.HP.COM; Wed, 27 Jan 88 13:23:08 pst
Received: from hplabsz by hplabsz; Wed, 27 Jan 88 13:25:15 pst
To: Jon L White <edsel!jonl@labrea.Stanford.EDU>
Cc: common-lisp-object-system@sail.stanford.edu
Subject: Re: Type-checking of slot values
In-Reply-To: Your message of Wed, 27 Jan 88 03:00:04 -0800.
<8801271100.AA25486@bhopal.lucid.com>
Date: Wed, 27 Jan 88 13:25:12 PST
Message-Id: <352.570317112@hplabsz>
From: kempf%hplabsz@hplabs.HP.COM
> My preference as stated before is to
> prohibit a rule *requiring* checking of slot values, except that under the
> extremal safety settings such checking *may* be required. Note that this
> phrasing grants permission for an implementation to do type-checking at all
> safety levels, if it so chooses.
This sounds consistent with CLtL policy on declarations to me.
> Incidentally, I would propose a benchmark of using defclass for defstruct,
> and see if there is *any* mode where the user suffers no slowdown [:type
> specifiers aren't the only hinderence to success here!]. Conversely, there
> should be a test case that asks whether there is *any* mode where all slot
> :type specifiers are always satisfied.
Well, since the change class protocol requires that an implementation be
able to modify the structure of an object while maintaining EQ identity,
there are implementations which could impose an extra level of indirection
into slot lookup. Alternatively, a class could keep track of all its
instances, but garbage collection becomes complicated. I had, at one time,
proposed a set of primitives to freeze the class structure about a certain
class, but there appeared to be little or no interest in this idea, and it
somehow got dropped. This would allow an instance implementation with one level
of indirection, but attempts to change the class would signal an error.
Alternatively, one could modify DEFCONSTANT to allow declaration of
constant structure as well as constant binding. As a general tool, this
obviously would be very difficult to implement, but for things like
classes and functions, which are named but for which the name/object
binding does not go through the symbol value cell, enforcing it would be
straightforward.
Of course, with real forwarding pointers, the amount of overhead in
slot lookup becomes much less, since the virtual memory system is
helping you.
jak
∂27-Jan-88 1358 Common-Lisp-Object-System-mailer Re: Method Combination Objects
Received: from Score.Stanford.EDU by SAIL.Stanford.EDU with TCP; 27 Jan 88 13:58:47 PST
Received: from hplabs.HP.COM by SCORE.STANFORD.EDU with TCP; Wed 27 Jan 88 13:53:07-PST
Received: from hplms2.HP.COM (hplms2) by hplabs.HP.COM with SMTP ; Wed, 27 Jan 88 13:55:36 PST
Received: from hplabsz.hpl.hp.com (hplabsz.hpl.hp.com) by hplms2.HP.COM; Wed, 27 Jan 88 13:55:16 pst
Received: from hplabsz by hplabsz; Wed, 27 Jan 88 13:57:23 pst
To: "David A. Moon" <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Cc: common-lisp-object-system@sail.stanford.edu
Subject: Re: Method Combination Objects
In-Reply-To: Your message of Wed, 27 Jan 88 12:34:00 -0500.
<19880127173423.8.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Wed, 27 Jan 88 13:57:19 PST
Message-Id: <866.570319039@hplabsz>
From: kempf%hplabsz@hplabs.HP.COM
> Append to the paragraph:
> "A method combination instance is a meta-object that encapsulates
> the method combination type and options specified by the
↑↑↑↑
> {\bf :method-combination} option to forms that specify generic
> function options."
I don't think you mean "type" in the sense of Common Lisp type here,
do you? Isn't "role" the correct technical term?
> (describe-method-concisely generic-function method method-combination)
Why is this any different from DESCRIBE? Presumably, a DESCRIBE method
could give the same information for a method object.
jak
∂27-Jan-88 1746 Common-Lisp-Object-System-mailer Re: Method Combination Objects
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 27 Jan 88 17:46:48 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 330071; Wed 27-Jan-88 20:46:45 EST
Date: Wed, 27 Jan 88 20:46 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: Method Combination Objects
To: kempf%hplabsz@hplabs.HP.COM
cc: common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: <866.570319039@hplabsz>
Message-ID: <19880128014644.1.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Wed, 27 Jan 88 13:57:19 PST
From: kempf%hplabsz@hplabs.HP.COM
> Append to the paragraph:
> "A method combination instance is a meta-object that encapsulates
> the method combination type and options specified by the
↑↑↑↑
> {\bf :method-combination} option to forms that specify generic
> function options."
I don't think you mean "type" in the sense of Common Lisp type here,
do you? Isn't "role" the correct technical term?
I mean "type", but not in the sense of Common Lisp type. "Type" is
the word other parts of the document use, e.g. 1-5 last paragraph,
1-36 heading near bottom of page, 2-28 fourth bullet. I'm not enamored
of the term, since it's easy to confuse with the formal notion of type,
but it's the term that the document uses.
Role is certainly not the correct term; at least, the way we've been using
it, it is an attribute of a method that is defined by a method-combination
[type]; it's not a synonym for a method-combination [type].
> (describe-method-concisely generic-function method method-combination)
Why is this any different from DESCRIBE? Presumably, a DESCRIBE method
could give the same information for a method object.
DESCRIBE would talk all about the method object at length, whereas
describe-method-concisely prints just one or two words that crisply
identify this method's role. In fact, do you think
describe-method-role-concisely would be a better name?
∂27-Jan-88 2015 Common-Lisp-Object-System-mailer call-method proposal prime prime
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 27 Jan 88 20:15:06 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 330153; Wed 27-Jan-88 23:15:15 EST
Date: Wed, 27 Jan 88 23:15 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: call-method proposal prime prime
To: common-lisp-object-system@SAIL.STANFORD.EDU
References: <19880115034035.4.MOON@EUPHRATES.SCRC.Symbolics.COM>,
<19880115034855.5.MOON@EUPHRATES.SCRC.Symbolics.COM>,
<2778248738-2219223@Jenner>,
<880115133053.3.GREGOR@SPIFF.parc.xerox.com>
Message-ID: <19880128041515.6.MOON@EUPHRATES.SCRC.Symbolics.COM>
I take it we have agreed on this. Here are the changes to the document.
In cases where the mail was unclear, I made some decisions. I hope there
is time to make these changes before we have to ship the documents to
X3J13. I apologize for the delay in getting this out; pulling it all
together has been a bigger job than I expected, and I had some other
things that had to be done first.
Chapter 1: No changes.
Chapter 2:
2-5: In "Tools for declarative method combination", remove
make-method-call, add call-method and make-method.
2-30 long form syntax of define-method-combination changes to:
\Defmac {define-method-combination} {\vtop{\hbox{name lambda-list }
\hbox{\paren{\star{\curly{method-group-specifier}}} }
\hbox{\brack{\paren {{\bf :arguments} \dot {\it lambda-list }}}}
\hbox{\star{\curly {declaration $\vert$ doc-string}}}
\hbox{\star{\curly{form}}}}}
or, in English, the list (:arguments . lambda-list) can optionally
appear before any declarations or documentation string. I've almost
certainly gotten the TeX wrong.
2-33 fifth paragraph: Remove the following sentences:
The function {\bf make-method-call} is also used in constructing the
Lisp form; it hides the implementation-dependent details of how
methods are called. Programmers always use {\bf make-method-call} to
translate from the lists of method objects produced by the method-group
specifiers to Lisp forms that invoke those methods.
Replace them with:
The effective method uses the macros {\bf call-method} and
{\bf make-method}. They hide the implementation-dependent details
of how methods are called. These macros have lexical scope and are
only available in an effective method Lisp form.
Programmers always translate a method object, an element of one of the
lists produced by the method-group specifiers, into a Lisp form that
invokes the method by constructing a form that invokes the
{\bf call-method} macro with the method object as its first subform
and a list of next-method objects as its second subform.
Programmers translate a Lisp form into a method object whose body
is that form with the {\bf make-method} macro. An invocation of
{\bf make-method} can only be used inside of an invocation of
{\bf call-method}.
Append the following new paragraph:
When an effective method has no effect other than to call a single
method, some implementations employ an optimization that uses the
single method directly as the effective method, thus avoiding
the need to create a new effective method. This optimization is
active when the effective method Lisp form consists entirely of
an invocation of the {\bf call-method} macro whose first subform
is a method object and whose second subform is {\bf nil}. Each
{\bf define-method-combination} body is responsible for stripping
off redundant invocations of {\bf progn}, {\bf and},
{\bf multiple-value-prog1}, and the like, if this optimization
is desired.
Append the following paragraph:
The list {\bf (:arguments . {\it lambda-list\/})} can optionally
appear before any declarations or documentation string. This is
useful when the method combination type performs some specific
behavior as part of the combined method and that behavior needs access
to the arguments to the generic function. Each parameter variable
defined by {\it lambda-list\/} is bound to a form that can be inserted
into the effective method. When this form is evaluated during
execution of the effective method, its value is the corresponding
argument to the generic function. If {\it lambda-list\/} is not
congruent to the generic function's lambda-list, additional
ignored parameters are automatically inserted until it is congruent.
Thus it is permissible for {\it lambda-list\/} to receive fewer
arguments than the number the generic function expects.
2-34 first paragraph: Replace the whole paragraph with:
The functions {\bf method-combination-error} and
{\bf invalid-method-error} can be called from the body
{\it forms\/} or from functions called by the body {\it forms\/}. The
actions of these two functions can depend on implementation-dependent
dynamic variables automatically bound before the generic function
{\bf compute-effective-method} is called.
2-34 through 2-36: Replace the entire Examples section with the following:
Most examples of the long form of {\bf define-method-combination} also
illustrate the use of the related functions that are provided as part
of the declarative method combination facility.
\screen!
;;; Examples of the short form of define-method-combination
(define-method-combination and :identity-with-one-argument t)
(defmethod func and ((x class1) y) ...)
;;; The equivalent of this example in the long form is:
(define-method-combination and
(&optional (order ':most-specific-first))
((around (:around))
(primary (and) :order order :required t))
(let ((form (if (rest primary)
`(and ,@(mapcar #'(lambda (method)
`(call-method ,method ()))
primary))
`(call-method ,(first primary) ()))))
(if around
`(call-method ,(first around)
(,@(rest around)
(make-method ,form)))
form)))
;;; Examples of the long form of define-method-combination
;The default method-combination technique
(define-method-combination standard ()
((around (:around))
(before (:before))
(primary () :required t)
(after (:after)))
(flet ((call-methods (methods)
(mapcar #'(lambda (method)
`(call-method ,method ()))
methods)))
(let ((form (if (or before after (rest primary))
`(multiple-value-prog1
(progn ,@(call-methods before)
(call-method ,(first primary)
,(rest primary)))
,@(call-methods (reverse after)))
`(call-method ,(first primary) ()))))
(if around
`(call-method ,(first around)
(,@(rest around)
(make-method ,form)))
form))))
;A simple way to try several methods until one returns non-nil
(define-method-combination or ()
((methods (or)))
`(or ,@(mapcar #'(lambda (method)
`(call-method ,method ()))
methods)))
;A more complete version of the preceding
(define-method-combination or
(&optional (order ':most-specific-first))
((around (:around))
(primary (or)))
;; Process the order argument
(case order
(:most-specific-first)
(:most-specific-last (setq primary (reverse primary)))
(otherwise (method-combination-error "~S is an invalid order.~@
:most-specific-first and :most-specific-last are the possible values."
order)))
;; Must have a primary method
(unless primary
(method-combination-error "A primary method is required."))
;; Construct the form that calls the primary methods
(let ((form (if (rest primary)
`(or ,@(mapcar #'(lambda (method)
`(call-method ,method ()))
primary))
`(call-method ,(first primary) ()))))
;; Wrap the around methods around that form
(if around
`(call-method ,(first around)
(,@(rest around)
(make-method ,form)))
form)))
;The same thing, using the :order and :required keyword options
(define-method-combination or
(&optional (order ':most-specific-first))
((around (:around))
(primary (or) :order order :required t))
(let ((form (if (rest primary)
`(or ,@(mapcar #'(lambda (method)
`(call-method ,method ()))
primary))
`(call-method ,(first primary) ()))))
(if around
`(call-method ,(first around)
(,@(rest around)
(make-method ,form)))
form)))
;This short-form call is behaviorally identical to the preceding
(define-method-combination or :identity-with-one-argument t)
;Order methods by positive integer qualifiers
;:around methods are disallowed to keep the example small
(define-method-combination example-method-combination ()
((methods positive-integer-qualifier-p))
`(progn ,@(mapcar #'(lambda (method)
`(call-method ,method ()))
(stable-sort methods #'<
:key #'(lambda (method)
(first (method-qualifiers method)))))))
(defun positive-integer-qualifier-p (method-qualifiers)
(and (= (length method-qualifiers) 1)
(typep (first method-qualifiers) '(integer 0 *))))
;;; Example of the use of :arguments
(define-method-combination progn-with-lock ()
((methods ()))
(:arguments object)
`(unwind-protect
(progn (lock (object-lock ,object))
,@(mapcar #'(lambda (method)
`(call-method ,method ()))
methods))
(unlock (object-lock ,object))))
\endscreen!
2-36: In the See Also field, remove make-method-call, add
call-method and make-method.
2-58 through 2-59: Delete the writeup for make-method-call.
Replace it with the following two writeups:
\begincom{call-method}\ftype{Macro}
\label Purpose:
The macro {\bf call-method} is used in method combination. It has
lexical scope and is only available within an effective method Lisp
form. It hides the implementation-dependent details of how methods
are called.
Programmers always translate a method object into a Lisp form that
invokes the method by constructing a form that invokes the
{\bf call-method} macro with the method object as its first subform
and a list of next-method objects as its second subform.
The {\bf call-next-method} function available to the method that
is the first subform will call the first method in the list that
is the second subform. The {\bf call-next-method} function
available in that method, in turn, will call the second
method in the list that is the second subform, and so on until
the list of next-methods is exhausted.
In place of a method object, as the first subform of {\bf call-method}
or as an element of the second subform of {\bf call-method},
a list can be used that is an invocation of the {\bf make-method}
macro.
\label Syntax:
\Defun {call-method} {method next-method-list}
\label See Also:
{\bf call-next-method}
{\bf define-method-combination}
{\bf make-method}
\endcom
\begincom{make-method}\ftype{Macro}
\label Purpose:
The macro {\bf make-method} is used in method combination. It has
lexical scope and is only available within an effective method Lisp
form. An invocation of {\bf make-method} can only be used inside of an
invocation of {\bf call-method}.
Programmers translate a Lisp form into a method object whose body
is that form with the {\bf make-method} macro. This is primarily
used when the next-method for {\bf call-next-method} is defined by
a form that calls several methods, rather than being a single
method object.
\label Syntax:
\Defun {make-method} {form}
\label See Also:
{\bf call-method}
{\bf call-next-method}
{\bf define-method-combination}
\endcom
∂27-Jan-88 2128 Common-Lisp-Object-System-mailer Typechecking
To: Common-lisp-object-system@SAIL.Stanford.EDU
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>
I think Moon must have gotten a bad chapter 1, because I cannot find the
quote he mentions in the file that I consider to be the definitive version.
The closest I can come is this:
``Because an implementation is required to check the type of the value
being stored in a slot only under the safest compiler safety setting and in the
interpreter, the value in a slot might fail to satisfy its type constraint.''
I believe this clearly states that violating the type constraint should
signal an error. There is no particularly pretty way to use the ``should
signal an error'' phrase here, so I expanded the definition of the phrase
inline. The use of the word ``only'' in the dependent clause beginning
with ``because'' combines with that ``because'' to state that the reason
that the value of the slot might fail to live up to the constraint is that
an implementation may or may not check the type on initialization and
stores.
The choices we have available to us are to require checking in all
cases, to require checking in at least the safest compiler compilation
setting and the interpreter, or to let the results be undefined. Stock
hardware people reject the first, and special-purpose people reject the last
(they want the results to be defined - to signal an error). Therefore, it
has to be ``should signal an error.'' We agreed long ago to abide by this
error terminology, and I won't accept backing down on that now.
About 2 or 3 paragraphs above the quote I reproduced is the following
statement about the :type option:
``Attempting to store a value in a slot which does not satisfy the type
should signal an error.''
-rpg-
∂28-Jan-88 0345 Common-Lisp-Object-System-mailer Type-checking of slot values
Received: from labrea.Stanford.EDU by SAIL.Stanford.EDU with TCP; 28 Jan 88 03:44:59 PST
Received: by labrea.Stanford.EDU; Thu, 28 Jan 88 03:45:07 PST
Received: from bhopal.lucid.com by edsel id AA23698g; Thu, 28 Jan 88 03:24:42 PST
Received: by bhopal id AA03293g; Thu, 28 Jan 88 03:28:33 PST
Date: Thu, 28 Jan 88 03:28:33 PST
From: Jon L White <edsel!jonl@labrea.Stanford.EDU>
Message-Id: <8801281128.AA03293@bhopal.lucid.com>
To: labrea!kempf%hplabs.HP.COM@labrea.Stanford.EDU
Cc: labrea!common-lisp-object-system%sail.stanford.edu@labrea.Stanford.EDU
In-Reply-To: kempf%hplabsz@hplabs.HP.COM's message of Wed, 27 Jan 88 13:25:12 PST <352.570317112@hplabsz>
Subject: Type-checking of slot values
re: Alternatively, one could modify DEFCONSTANT to allow declaration of
constant structure as well as constant binding.
I like that idea [of having declared constant classes]. A related topic is
"lexical" structures so that can be allocated/de-allocated in a "stack"
discipline [akin to how the strongly-typed languages would do it]. However,
given the current problems and focus of CLOS specification, this may not be
the right time to bring such issues up.
Ultimately, the quest for performance may require some thinking along these
lines. But (sigh) another time, another place . . .
-- JonL --
∂28-Jan-88 0803 Common-Lisp-Object-System-mailer Re: Method Combination Objects
Received: from RELAY.CS.NET by SAIL.Stanford.EDU with TCP; 28 Jan 88 08:03:06 PST
Received: from relay2.cs.net by RELAY.CS.NET id aa17775; 28 Jan 88 10:53 EST
Received: from csc.ti.com by RELAY.CS.NET id ab27897; 28 Jan 88 10:41 EST
Received: from Jenner by tilde id AA03536; Thu, 28 Jan 88 08:07:15 CST
Message-Id: <2779366011-5127571@Jenner>
Date: Thu, 28 Jan 88 08:06:51 CST
From: Patrick H Dussud <dussud@jenner.csc.ti.com>
To: Common-Lisp-Object-System@SAIL.STANFORD.EDU
Subject: Re: Method Combination Objects
In-Reply-To: Msg of Wed, 27 Jan 88 16:01 EST from "David A. Moon" <Moon@scrc-stony-brook.arpa>
Since method-combination-instance (method-combination-object) must be
called before ensure-generic-function is called, its first argument is
actually a prototype of the generic function.
On 13 January, Danny said
[method-combination-instance] allows specialization on the class of
the generic function as well as on the name. Although useful, this
might not be important because compute-effective-method also allows
specialization on both the generic function and method combination
object.
Given this, and what you just pointed out, I think it was a mistake to make
the generic function an argument here. Thus I think the arguments should
be (method-combination-object name options) => object. This doesn't
affect chapter 1 or 2.
I think this is right.
Patrick.
∂28-Jan-88 0804 Common-Lisp-Object-System-mailer call-method proposal
Received: from RELAY.CS.NET by SAIL.Stanford.EDU with TCP; 28 Jan 88 08:04:32 PST
Received: from relay2.cs.net by RELAY.CS.NET id ac17775; 28 Jan 88 10:53 EST
Received: from csc.ti.com by RELAY.CS.NET id ad27897; 28 Jan 88 10:41 EST
Received: from Jenner by tilde id AA03795; Thu, 28 Jan 88 08:21:29 CST
Message-Id: <2779366878-5179661@Jenner>
Date: Thu, 28 Jan 88 08:21:18 CST
From: Patrick H Dussud <dussud@jenner.csc.ti.com>
To: common-lisp-object-system@SAIL.STANFORD.EDU
Subject: call-method proposal
In-Reply-To: Msg of Wed, 27 Jan 88 23:15 EST from "David A. Moon" <Moon@scrc-stony-brook.arpa>
Date: Wed, 27 Jan 88 23:15 EST
From: "David A. Moon" <Moon@scrc-stony-brook.arpa>
Subject: call-method proposal prime prime
I take it we have agreed on this. Here are the changes to the document.
In cases where the mail was unclear, I made some decisions. I hope there
is time to make these changes before we have to ship the documents to
X3J13. I apologize for the delay in getting this out; pulling it all
together has been a bigger job than I expected, and I had some other
things that had to be done first.
I basically agree with the text, I noticed that the distinction between
"there are no more next methods" and "call-next-method cannot be called"
is not there anymore. I don't object though.
Patrick.
∂28-Jan-88 0911 Common-Lisp-Object-System-mailer Method Combination Objects
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 28 Jan 88 09:11:04 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 330415; Thu 28-Jan-88 11:59:35 EST
Date: Thu, 28 Jan 88 11:59 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Method Combination Objects
To: Common-Lisp-Object-System@SAIL.STANFORD.EDU
References: <19880127173423.8.MOON@EUPHRATES.SCRC.Symbolics.COM>,
<19880127210152.5.MOON@EUPHRATES.SCRC.Symbolics.COM>
Message-ID: <19880128165933.0.MOON@EUPHRATES.SCRC.Symbolics.COM>
Revised, based on Gregor's and Jim's comments. Nothing new here, just
amalgamation of previous mail.
First, the impact on chapters 1 and 2. Page numbers refer to the 20 Jan
1988 drafts.
1-33 last paragraph (excluding the implementation note), second sentence.
Replace this sentence with:
"The generic function {\bf compute-effective-method} receives as
arguments the generic function, the method combination object,
and the sorted list of applicable methods."
Append to the paragraph:
"A method combination object is a meta-object that encapsulates
the method combination type and options specified by the
{\bf :method-combination} option to forms that specify generic
function options."
1-40: This is optional, but I think we should add method combination
objects to the list of meta-objects. Each method combination object
is an instance of a subclass of the class {\bf method-combination}.
I don't think we need to name any of the subclasses here, not even
{\bf standard-method-combination}; that's chapter 3 material for now.
2-42 documentation method signatures: Add two for method-combination
(italic) method-combination (bold), for documentation and for
setf of documentation. On the next page, under arguments, the first
bullet should mention method combination objects too.
2-43 ensure-generic-function arguments: Nothing really needs to be
changed, since the value of the :method-combination argument is not
described at all in the latest draft. However, I suggest two sentences
should be added:
"The {\bf :method-combination} argument is a method combination
object. A method combination object is a meta-object that
encapsulates the method combination type and options specified by the
{\bf :method-combination} option to forms that specify generic
function options."
That's all that has to be changed in chapters 1 and 2. Here's an
approximation of what goes into chapter 3. I have done no editing for
style here, only content. I've left out the design rationale this
time, to keep this small. Consult the referenced messages of the
referenced messages if you want to see it again.
Method Combination Naming Layer
This layer is concerned with mapping method combination names and
options, as seen in the :method-combination option to defgeneric, to
method combination meta-objects.
(method-combination-object method-combination-name
method-combination-options)
=> method-combination
is how a method combination name and a list of options are converted
into an object. define-method-combination expands into a defmethod
for method-combination-object. remove-method can be used to
undefine a method combination type.
method-combination-object signals an error if
method-combination-name is unrecognized. Each method for
method-combination-object signals an error if the
method-combination-options are unrecognized or there are
too many or too few of them.
method-combination-object might return the same object each time
it is called with given arguments, or it might make a new object.
(method-combination-name method-combination) => symbol
(method-combination-options method-combination) => list
These two generic functions perform the inverse mapping.
Method Combination Object Layer
method-combination
This class is a superclass of all classes of method combination.
standard-method-combination
This class is the class of the method combination object used by default
when :method-combination is not specified.
Other implementation-dependent subclasses of method-combination exist.
For example, all invocations of the short form of
define-method-combination probably use one class, and each invocation of
the long form of define-method-combination probably defines a new class
which has a superclass in common with standard-method-combination.
CLOS does not specify how many of these classes there are nor what
their names are.
(compute-effective-method generic-function method-combination method-list)
=> effective-method-form
This generic function performs part 3 of the determination of the
effective method. define-method-combination works through methods that
specialize the second parameter.
(describe-method-role-concisely generic-function method method-combination)
This generic function prints a description of the method's role onto
*standard-output*. The value returned is ignored. The description
is generally determined jointly by the method-combination and the
method's qualifiers. The description describes only the method's
role, not its generic function and not its parameter specializers;
those would be described by the caller or implied by context (e.g.
if the caller is printing a table of methods for a particular
generic function). define-method-combination defines a method for
describe-method-role-concisely that uses the :description option of
the long form to control what it prints.
Other generic functions specialized by method combinations are not
currently defined by CLOS, but program development environments are
likely to have some.
A generic function object records a method combination object, rather
than the name and options of a method combination type. This changes
the initialization arguments and structural access functions for generic
functions from what is in chapter 3 now. There will be a structural
access function that, given a generic function object, returns a method
combination object. defgeneric calls method-combination-object before
it calls ensure-generic-function.
Example
The short form of define-method-combination could have been defined
as follows:
(defclass short-form-method-combination
(method-combination)
((name :initarg name :reader method-combination-name)
(order :initarg order)
(documentation :initarg documentation :reader documentation)
(operator :initarg operator)
(identity-with-one-argument :initarg identity-with-one-argument)))
(defmethod method-combination-options ((mc short-form-method-combination))
(list (slot-value mc 'order)))
(defmethod compute-effective-method (generic-function
(mc short-form-method-combination)
methods)
(let ((primary-methods (remove (list (slot-value mc 'name))
methods :key #'method-qualifiers
:test-not #'equal))
(around-methods (remove '(:around)
methods :key #'method-qualifiers
:test-not #'equal)))
(when (eq (slot-value mc 'order) ':most-specific-last)
(setq primary-methods (reverse primary-methods)))
(dolist (method (set-difference methods
(union primary-methods around-methods)))
(invalid-method-error method
"The qualifiers of ~S, ~:S, are not ~S or ~S"
method (method-qualifiers method)
(list (slot-value mc 'name)) '(:around)))
(let ((form (if (or (rest primary-methods)
(not (slot-value mc 'identity-with-one-argument)))
`(,(slot-value mc 'operator)
,@(mapcar #'(lambda (method)
`(call-method ,method ()))
primary-methods))
`(call-method ,(first primary-methods) ()))))
(if around-methods
`(call-method ,(first around-methods)
(,@(rest around-methods)
(make-method ,form)))
form))))
(defmethod describe-method-concisely
(generic-function
method
(method-combination short-form-method-combination))
(declare (ignore generic-function))
(write-string (string-downcase (string (first (method-qualifiers method))))))
(defmacro define-method-combination
(name &key (documentation nil)
(operator name)
(identity-with-one-argument nil))
`(defmethod method-combination-object
((name (eql ',name))
options)
(apply #'(lambda (&optional (order ':most-specific-first))
(check-type order (member :most-specific-first
:most-specific-last))
(make-instance 'short-form-method-combination
'name ',name
'order order
'documentation ',documentation
'operator ',operator
'identity-with-one-argument
',identity-with-one-argument))
options)))
Example of Defining a Method Combination Type via Inheritance
;This example defines a method combination type that is similar
;to standard method combination, except that it also allows :or
;methods. The :or methods are executed after the :before methods,
;before the :after methods, inside the :around methods, and before
;the primary method. The primary method is only called if all the
;:or methods return nil; if any :or method returns non-nil, its
;value becomes the value of the generic function (or the value
;returned by call-next-method in the least specific :around method)
;in place of the values of the most specific primary method.
;This assumes one particular code analysis tool, whose
;details I will not try to explain here.
;Those assumptions are not critical.
;I'm assuming we don't want to try to extend the define-method-combination
;macro so that it could exploit inheritance. Instead I will
;define the example directly in terms of the next layer down.
(defclass standard-method-combination-with-or
(standard-method-combination)
())
(defmethod method-combination-object
((name (eql 'standard-with-or))
options)
(unless (null options)
(error "standard-with-or method combination does not accept options"))
(make-instance 'standard-method-combination-with-or))
;This uses call-next-method to get the effective method in the absence
;of any :or methods, then it modifies the effective method form to
;incorporate the :or methods in an OR special form wrapped around the
;call to the most specific primary method.
(defmethod compute-effective-method (generic-function
(mc standard-method-combination-with-or)
methods)
(let ((or-methods (remove '(:or) methods :key #'method-qualifiers
:test-not #'equal))
(other-methods (remove '(:or) methods :key #'method-qualifiers
:test #'equal)))
(lt:copyforms #'(lambda (subform kind usage)
(declare (ignore usage))
(if (and (listp kind) (listp subform)
(eq (first subform) 'call-method)
(null (method-qualifiers (second subform))))
;; Put or methods before primary method
(values `(or ,@(mapcar #'(lambda (method)
`(call-method ,method ()))
or-methods)
,subform)
t)
;; Leave all other subforms of effective method alone
subform))
(call-next-method generic-function mc other-methods))))
∂28-Jan-88 1147 Common-Lisp-Object-System-mailer reinitialization protocol
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 28 Jan 88 11:47:20 PST
Received: from Semillon.ms by ArpaGateway.ms ; 28 JAN 88 11:47:45 PST
Date: Thu, 28 Jan 88 11:45 PST
From: Gregor.pa@Xerox.COM
Subject: reinitialization protocol
To: common-lisp-object-system@SAIL.STANFORD.EDU
Fcc: BD:>Gregor>mail>outgoing-mail-1.text
Message-ID: <880128114541.6.GREGOR@SPIFF.parc.xerox.com>
Line-fold: no
Here is some pseudo code for the re-initialization protocol that Danny
and I worked out.
;;;; The re-initialization protocol.
(defmethod reinitialize-instance ((object standard-object) &rest reinit-args)
(let* ((arglist (list object))
(acceptable-args
(union
(method-keyword-arguments #'initialize-instance arglist)
(method-keyword-arguments #'reinitialize-instance arglist)
(class-all-slot-initargs (class-of object)))))
;; check the keyword arguments
(zl:loop (key in reinit-args by cddr)
(or (member key acceptable-args) (error ...)))
;; now initialize the instance
(apply #'initialize-instance object
:allow-other-keys 't
(default-init-args object reinit-args))
;; update all dependents
(loop (dep in (all-dependents object))
(apply #'update-dependent object dependent reinit-args))
nil))
;;;
;;; Generic functions for managing the dependents of an object. This is
;;; part of the instance re-initialization protocol. How dependents are
;;; stored is implementation dependent. Some subclasses of
;;; standard-object which know that they are in fact going to have lots
;;; of dependents may want to replace this triad of methods with methods
;;; which actually store the value in a slot.
;;;
(defmethod add-dependent ((object standard-object)
(dependent standard-object))
;; Add dependent as a dependent of object.
)
(defmethod remove-dependent ((object standard-object)
(dependent standard-object))
;; Remove dependent as a dependent of object.
)
(defmethod all-dependents ((object standard-object))
;; Returns the list of all dependents of the object.
)
-------
∂28-Jan-88 1152 Common-Lisp-Object-System-mailer class updating protocol
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 28 Jan 88 11:52:37 PST
Received: from Semillon.ms by ArpaGateway.ms ; 28 JAN 88 11:53:27 PST
Date: Thu, 28 Jan 88 11:51 PST
From: Gregor.pa@Xerox.COM
Subject: class updating protocol
To: common-lisp-object-system@SAIL.STANFORD.EDU
Fcc: BD:>Gregor>mail>outgoing-mail-1.text
Message-ID: <880128115133.7.GREGOR@SPIFF.parc.xerox.com>
Line-fold: no
Here is some pseudo code for the new class updating protocol. This code
tries to take all the comments we got in Boston into account. Please
try to comment on this soon as the rest of the mop re-design depends on
it.
As you read this, some things which are not specifically specified are:
class-access-keys is a generic function which returns the access keys
for a class. This is used to interface to the symbolic access layer.
As we discussed in Boston, there is no longer any reference to index
numbers, instead, access-keys (often symbols) are used to talk
symbolically about the `cells' which standard-instance-access
references.
Also notes that this is based on the instance re-initialization stuff we
sent out in a previous message.
;;;; The class updating protocol.
;;;
;;; This is called when a class is reinitialized, and the dependent has
;;; been recorded as one of the dependents of that class. It is supposed
;;; to make sure the dependent class is updated to take the change into
;;; account.
;;;
(defmethod update-dependent :around ((reinitialized-class standard-class)
(dependent standard-class)
&allow-other-keys)
(let ((old-access-keys (class-access-keys dependent)))
(call-next-method)
(unless (equal old-access-keys (class-access-keys dependent))
;; Implementation specific code to account for the fact that
;; the access keys for this class have changed. This will
;; cause the optimization of standard-instance-access to
;; continue to work.
;; This may include a call to make-instance-obsolete.
)))
(defmethod update-dependent ((reinitialized-class standard-class)
(dependent standard-class)
&key direct-superclasses
direct-slots
direct-options)
;; When we are called, dependent is finalized since our finalize
;; inheritance method is what recorded us as a dependent. We
;; have to do whatever updating is required to keep us finalized.
;; This includes:
;; - recomputing our class-precedence-list
;; go through the old and new cpls, calling remove-dependent
;; and add-dependent to update our dependents.
;; - recomputing our slots, this may change the value that
;; class-access-keys will be returning.
;; - go through the old and new slots adding and removing
;; automatically generated reader and writer methods as
;; required.
)
(defmethod finalize-inheritance ((class standard-class))
;; When we are called, the class is supposed to not be finalized.
;; We are supposed to ensure that it is finalized, that an instance
;; can be created. But sometimes we are called redundantly. First
;; we check to see if we are already finalized, if we are, we do
;; nothing. If we aren't, we set cpl and slots to NIL and then call
;; update-dependent with only two arguments, each of which is the
;; class. Once update dependent returns, we set class-finalized-p
;; of the class to T.
)
(defmethod reinitialize-instance :before ((class standard-class)
&key direct-superclasses
direct-slots
direct-options)
;; unhook old direct-subclass pointers
)
;;;
;;; When this is called, direct-superclasses must be a list of class
;;; objects, direct-slots must be a list of slot description objects
;;; and direct options is a list of class options as in defclass.
;;;
(defmethod initialize-instance :after ((class standard-class)
&key direct-superclasses
direct-slots
direct-options)
;; hook up new direct-subclass pointers
;; Store the values we get passed in the instance.
)
-------
∂28-Jan-88 1804 Common-Lisp-Object-System-mailer call-method proposal prime prime
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 28 Jan 88 18:04:08 PST
Received: from Semillon.ms by ArpaGateway.ms ; 28 JAN 88 17:29:42 PST
Date: Thu, 28 Jan 88 17:27 PST
From: Gregor.pa@Xerox.COM
Subject: call-method proposal prime prime
To: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
cc: common-lisp-object-system@SAIL.STANFORD.EDU
Fcc: BD:>Gregor>mail>outgoing-mail-1.text
In-Reply-To: <19880128041515.6.MOON@EUPHRATES.SCRC.Symbolics.COM>
Message-ID: <880128172740.3.GREGOR@SPIFF.parc.xerox.com>
Line-fold: no
Date: Wed, 27 Jan 88 23:15 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
I take it we have agreed on this. Here are the changes to the document.
In cases where the mail was unclear, I made some decisions. I hope there
is time to make these changes before we have to ship the documents to
X3J13. I apologize for the delay in getting this out; pulling it all
together has been a bigger job than I expected, and I had some other
things that had to be done first.
This is all fine except for one small thing. Since I sent this proposal
out, I have realized that (what you are calling) make-method isn't
really a lexical macro, it is just a special symbol which marks the car
of lists which appear in the second argument to call-method. There is
no problem with that particularly. I do think it means we should switch
the name back to EFFECTIVE-METHOD or just METHOD since it really doesn't
make anything at all.
-------
∂28-Jan-88 1838 Common-Lisp-Object-System-mailer call-method proposal prime prime
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 28 Jan 88 18:38:27 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 331156; Thu 28-Jan-88 21:38:37 EST
Date: Thu, 28 Jan 88 21:38 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: call-method proposal prime prime
To: common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: <880128172740.3.GREGOR@SPIFF.parc.xerox.com>
Message-ID: <19880129023837.1.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Thu, 28 Jan 88 17:27 PST
From: Gregor.pa@Xerox.COM
This is all fine except for one small thing. Since I sent this proposal
out, I have realized that (what you are calling) make-method isn't
really a lexical macro, it is just a special symbol which marks the car
of lists which appear in the second argument to call-method. There is
no problem with that particularly. I do think it means we should switch
the name back to EFFECTIVE-METHOD or just METHOD since it really doesn't
make anything at all.
I noticed that MAKE-METHOD is never actually macroexpanded, but I think
it is easier for the user to think of it as a local macro that changes a
form into a method, even though it's not implemented that way. I don't
feel real strongly about this, but unless you feel strongly let's leave
it alone.
∂29-Jan-88 0800 Common-Lisp-Object-System-mailer Re: class updating protocol
Received: from RELAY.CS.NET by SAIL.Stanford.EDU with TCP; 29 Jan 88 08:00:11 PST
Received: from relay2.cs.net by RELAY.CS.NET id af05245; 29 Jan 88 10:46 EST
Received: from csc.ti.com by RELAY.CS.NET id aj05448; 29 Jan 88 10:33 EST
Received: from Jenner by tilde id AA26800; Fri, 29 Jan 88 08:10:14 CST
Message-Id: <2779452680-5011654@Jenner>
Date: Fri, 29 Jan 88 08:11:20 CST
From: Patrick H Dussud <DUSSUD@jenner.csc.ti.com>
To: common-lisp-object-system@SAIL.STANFORD.EDU
Subject: Re: class updating protocol
In-Reply-To: Msg of Thu, 28 Jan 88 11:51 PST from Gregor.pa@xerox.com
;;;; The class updating protocol.
I don't object to the principles of this protocol. I have some specific
comment here, and I sent some comments about reinitialize-instance earlier
this week.
;;;
;;; This is called when a class is reinitialized, and the dependent has
;;; been recorded as one of the dependents of that class. It is supposed
;;; to make sure the dependent class is updated to take the change into
;;; account.
;;;
(defmethod update-dependent :around ((reinitialized-class standard-class)
(dependent standard-class)
&allow-other-keys)
(let ((old-access-keys (class-access-keys dependent)))
(call-next-method)
(unless (equal old-access-keys (class-access-keys dependent))
;; Implementation specific code to account for the fact that
;; the access keys for this class have changed. This will
;; cause the optimization of standard-instance-access to
;; continue to work.
;; This may include a call to make-instance-obsolete.
)))
(defmethod update-dependent ((reinitialized-class standard-class)
(dependent standard-class)
&key direct-superclasses
direct-slots
direct-options)
;; When we are called, dependent is finalized since our finalize
;; inheritance method is what recorded us as a dependent. We
;; have to do whatever updating is required to keep us finalized.
;; This includes:
;; - recomputing our class-precedence-list
;; go through the old and new cpls, calling remove-dependent
;; and add-dependent to update our dependents.
;; - recomputing our slots, this may change the value that
;; class-access-keys will be returning.
;; - go through the old and new slots adding and removing
;; automatically generated reader and writer methods as
;; required.
)
Does update-dependent call update-dependent on its dependents, or is the
dependent structure flat? This probably needs to be specified.
(defmethod finalize-inheritance ((class standard-class))
;; When we are called, the class is supposed to not be finalized.
;; We are supposed to ensure that it is finalized, that an instance
;; can be created. But sometimes we are called redundantly. First
;; we check to see if we are already finalized, if we are, we do
;; nothing. If we aren't, we set cpl and slots to NIL and then call
;; update-dependent with only two arguments, each of which is the
;; class. Once update dependent returns, we set class-finalized-p
;; of the class to T.
)
Why does finalize-inheritance have to do its work by calling
(UPDATE-DEPENDENT class class)? It seems backward to me. Why can't
UPDATE-DEPENDENT call (FINALIZE-INHERITANCE dependent),
and FINALIZE-INHERITANCE do the slot and CPL computation?
Patrick.
∂29-Jan-88 0905 Common-Lisp-Object-System-mailer Re: reinitialization protocol
Received: from Score.Stanford.EDU by SAIL.Stanford.EDU with TCP; 29 Jan 88 09:05:21 PST
Received: from hplabs.HP.COM by SCORE.STANFORD.EDU with TCP; Fri 29 Jan 88 08:48:59-PST
Received: from hplms2.HP.COM (hplms2) by hplabs.HP.COM with SMTP ; Fri, 29 Jan 88 08:51:33 PST
Received: from hplabsz.hpl.hp.com (hplabsz.hpl.hp.com) by hplms2.HP.COM; Fri, 29 Jan 88 08:51:08 pst
Received: from hplabsz by hplabsz; Fri, 29 Jan 88 08:53:16 pst
To: Gregor.pa@Xerox.COM
Cc: common-lisp-object-system@sail.stanford.edu
Subject: Re: reinitialization protocol
In-Reply-To: Your message of Thu, 28 Jan 88 11:45:00 -0800.
<880128114541.6.GREGOR@SPIFF.parc.xerox.com>
Date: Fri, 29 Jan 88 08:53:13 PST
Message-Id: <27799.570473593@hplabsz>
From: kempf%hplabsz@hplabs.HP.COM
> ;;; Generic functions for managing the dependents of an object. This is
Perhaps this is in the mop document, but, can you give a short, high level
description of what exactly a "dependent" is? With an example? I briefly
looked over my back mail and couldn't find anything. Thanks.
jak
∂29-Jan-88 0927 Common-Lisp-Object-System-mailer Re: class updating protocol
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 29 Jan 88 09:27:15 PST
Received: from Cabernet.ms by ArpaGateway.ms ; 29 JAN 88 09:27:24 PST
Date: 29 Jan 88 09:23 PST
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Re: class updating protocol
In-reply-to: Patrick H Dussud <DUSSUD@jenner.csc.ti.com>'s message of Fri, 29
Jan 88 08:11:20 CST
To: DUSSUD@jenner.csc.ti.com
cc: common-lisp-object-system@SAIL.STANFORD.EDU
Message-ID: <880129-092724-1477@Xerox>
Does update-dependent call update-dependent on its dependents,
or is the dependent structure flat? This probably needs to be
specified.
The intent was that update-dependent would flat. Of course, if the way a
particlar method on update-dependent works is to call reinitinaize-instance then
...
Why does finalize-inheritance have to do its work by calling
(UPDATE-DEPENDENT class class)? It seems backward to me. Why can't
UPDATE-DEPENDENT call (FINALIZE-INHERITANCE dependent), and
FINALIZE-INHERITANCE do the slot and CPL computation?
Because finalize-inheritance is defined to do nothing after the first time that
inheritance is finalized. This is to avoid having redundant calls to
finalize-inheritance recompute each time.
danny
∂29-Jan-88 1106 Common-Lisp-Object-System-mailer Re: Comments on latest draft documents
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 29 Jan 88 11:06:33 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 331555; Fri 29-Jan-88 14:06:48 EST
Date: Fri, 29 Jan 88 14:06 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: Comments on latest draft documents
To: Linda DeMichiel <LGD@SAIL.STANFORD.EDU>
cc: Common-Lisp-Object-System@SAIL.STANFORD.EDU
In-Reply-To: The message of 28 Jan 88 18:26 EST from Linda DeMichiel <LGD@SAIL.Stanford.EDU>
Message-ID: <19880129190654.7.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: 28 Jan 88 1526 PST
From: Linda DeMichiel <LGD@SAIL.Stanford.EDU>
In your message ``Comments on latest draft documents,'' you write:
2-17 class-name: The name of a class should not be restricted in type. The
method signature should specialize new-value with t, the arguments should
say new-value is typically a symbol, and the semicolon clause under
values should be deleted. While a class's proper name is a symbol
unless symbol-class is somehow extended, class-name should be allowed
to be any object. One proposed extension we discussed earlier has
class-name a list of classes.
Neither Dick nor I recall this having been decided. If this is really
what you want, I think you should bring this up for a vote on the list.
I don't think anything was decided. My point is that it's silly, in my
opinion, to use parameter specializers on new-value arguments to setf
methods as a way of doing type-checking (rather than specialization), and
more importantly that I don't think the CLOS specification should imply
that if you need to store a different type of value, you have to define
your own method. I suppose this comes down to the issue of what is the
contract of the method and what is the contract of the generic function,
again. Since we agreed not to try to solve that in chapter 2 this time
around, I would be happier if the method signatures didn't specialize
the new-value arguments.
If anyone wants to argue for or against the class-name function being
restricted by the CLOS specification to return only symbols, this is
the place to speak up about it.
2-41 documentation method signatures: The parameter specializer name
for new-value should be t, not string. CLtL doesn't say anywhere what
values are allowed, but a reasonable inference is that NIL is allowed,
and "documentation information" might have been meant to include some
sort of structures as well. The allowable types here are a matter for
CL to define, not for CLOS to legislate.
t doesn't strike us as a reasonable generalization of string and nil.
It's the only one that CLOS has, since it doesn't allow OR. But
my point wasn't that the specializer should be (OR STRING NULL); my point
was that it's not up to CLOS to define the allowable types here, and as
far as the CLOS specification goes, the new-value parameter should not be
restricted.
It seems to us that adding signatures for setf methods for (eql nil)
is a more sensible thing to do.
To me that's a much less sensible thing to do! The need to duplicate
the method shows that using the parameter specializer to do type-checking,
rather than specialization, was a mistake. At least that's how I see it.
I suppose none of this really matters, because it's only the method
signatures in the document, and we already agreed that those are going
to be discovered to be incorrect in the future.
∂29-Jan-88 1134 Common-Lisp-Object-System-mailer Re: reinitialization protocol
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 29 Jan 88 11:34:24 PST
Received: from Cabernet.ms by ArpaGateway.ms ; 29 JAN 88 11:32:35 PST
Date: 29 Jan 88 11:31 PST
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Re: reinitialization protocol
In-reply-to: kempf%hplabsz@hplabs.HP.COM's message of Fri, 29 Jan 88 08:53:13
PST
To: kempf%hplabsz@hplabs.HP.COM
cc: Gregor.pa@Xerox.COM, common-lisp-object-system@sail.stanford.edu
Message-ID: <880129-113235-1700@Xerox>
> ;;; Generic functions for managing the dependents of an
object. This is
Perhaps this is in the mop document, but, can you give a short,
high level description of what exactly a "dependent" is? With an
example? I briefly looked over my back mail and couldn't find
anything. Thanks.
The concept of dependent is not in the document that you received. Patrick and
Dave suggested at the Cambridge meeting that only some subclasses of a given
class need be updated when the class changes (A class that never has had its
inheritance finalized need not be updated). They suggested that a subclass
could register itself with a superclass when it wanted to be notified of changes
to that superclass.
The generalization is as follows. An object O2 is dependent on O1 if it
registers itself as such. The intent is that O2 will be notified if O1 changes
in certain ways. Of course, methods on O1 must cooperate to the extent that
they call update-dependent for each dependent, but they need not know anything
about what update-dependent will do to O2. This use of registered dependents has
had a long and successful history in Smalltalk in their model view controller
paradigm, where views are dependents on the objects they are viewing.
∂29-Jan-88 1146 Common-Lisp-Object-System-mailer Re: class updating protocol
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 29 Jan 88 11:46:18 PST
Received: from Semillon.ms by ArpaGateway.ms ; 29 JAN 88 11:45:11 PST
Date: Fri, 29 Jan 88 11:42 PST
From: Gregor.pa@Xerox.COM
Subject: Re: class updating protocol
To: Patrick H Dussud <DUSSUD@jenner.csc.ti.com>
cc: common-lisp-object-system@SAIL.STANFORD.EDU
Fcc: BD:>Gregor>mail>outgoing-mail-1.text
In-Reply-To: <2779452680-5011654@Jenner>
Message-ID: <880129114214.1.GREGOR@SPIFF.parc.xerox.com>
Line-fold: no
Date: Fri, 29 Jan 88 08:11:20 CST
From: Patrick H Dussud <DUSSUD@jenner.csc.ti.com>
Does update-dependent call update-dependent on its dependents, or is the
dependent structure flat? This probably needs to be specified.
The dependent structure is flat.
Why does finalize-inheritance have to do its work by calling
(UPDATE-DEPENDENT class class)? It seems backward to me. Why can't
UPDATE-DEPENDENT call (FINALIZE-INHERITANCE dependent),
and FINALIZE-INHERITANCE do the slot and CPL computation?
The idea was that finalize-inheritance was a stupid function the user
could call. Update dependent is a function that gets called with
keyword arguments telling it what happened. When it gets called with no
keyword arguments it means "something happened just make sure everything
is OK". Users could add keywords to the list it gets called with to
make it even smarter.
-------
∂29-Jan-88 1151 Common-Lisp-Object-System-mailer Re: reinitialization protocol
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 29 Jan 88 11:51:37 PST
Received: from Semillon.ms by ArpaGateway.ms ; 29 JAN 88 11:48:28 PST
Date: Fri, 29 Jan 88 11:46 PST
From: Gregor.pa@Xerox.COM
Subject: Re: reinitialization protocol
To: kempf%hplabsz@hplabs.HP.COM
cc: common-lisp-object-system@SAIL.STANFORD.EDU
Fcc: BD:>Gregor>mail>outgoing-mail-1.text
In-Reply-To: <27799.570473593@hplabsz>
Message-ID: <880129114646.2.GREGOR@SPIFF.parc.xerox.com>
Line-fold: no
Date: Fri, 29 Jan 88 08:53:13 PST
From: kempf%hplabsz@hplabs.HP.COM
> ;;; Generic functions for managing the dependents of an object. This is
Perhaps this is in the mop document, but, can you give a short, high level
description of what exactly a "dependent" is? With an example? I briefly
looked over my back mail and couldn't find anything. Thanks.
Dependents are based on the idea Patrick proposed in Boston that a
class, when it depends on the state of another class, would record
itself as a dependent to be notified of any changes.
The standard methods arrange that:
For all C1,C2 if member(C2, cpl(C1)) then C1 is a dependent of C2.
In english, whenever a class C1 inherits from another class C2, C1 is a
dependent of C2. The fact that C1 is recorded as a dependent of C2
means that whenever C2 changes, C1 will have update dependent called on
it.
-------
∂29-Jan-88 1247 Common-Lisp-Object-System-mailer call-method proposal prime prime
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 29 Jan 88 12:47:16 PST
Received: from Semillon.ms by ArpaGateway.ms ; 29 JAN 88 12:47:47 PST
Date: Fri, 29 Jan 88 12:45 PST
From: Gregor.pa@Xerox.COM
Subject: call-method proposal prime prime
To: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
cc: common-lisp-object-system@SAIL.STANFORD.EDU
Fcc: BD:>Gregor>mail>outgoing-mail-1.text
In-Reply-To: <19880129023837.1.MOON@EUPHRATES.SCRC.Symbolics.COM>
Message-ID: <880129124557.4.GREGOR@SPIFF.parc.xerox.com>
Line-fold: no
Date: Thu, 28 Jan 88 21:38 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
I noticed that MAKE-METHOD is never actually macroexpanded, but I think
it is easier for the user to think of it as a local macro that changes a
form into a method, even though it's not implemented that way. I don't
feel real strongly about this, but unless you feel strongly let's leave
it alone.
I don't know how strongly I feel, but let me show you the case that
bothers me, and if it doesn't bother you too much we'll leave it.
The general form of the case is when you don't construct the second
argument to call-next-method in a special place, so you have the whole
call-method form laid out in front of you. Suppose you knew there was
one around method and two or methods. Lets just say that was a special
kind of method combination you had. It would look like:
(define-method-combination 1-n-2 ()
((around (:around))
(or (:or)))
(let ((around (car around))
(or-1 (car or))
(or-2 (cadr or)))
`(call-method ,around
((make-method (or ,or-1 ,or-2))))))
It seems like when the user sees that case they are going to start
realizing pretty quick that make-method isn't really a lexical macro.
There is this whole question of when naivete is helpful and when it is
confusing. I kind of believe that in this case, the naive model we are
proposing might confuse people without them knowing why.
But as I said before if this doesn't bother anyone else I am will to let it
go.
-------
∂29-Jan-88 1331 Common-Lisp-Object-System-mailer Re: class updating protocol
Received: from RELAY.CS.NET by SAIL.Stanford.EDU with TCP; 29 Jan 88 13:31:47 PST
Received: from relay2.cs.net by RELAY.CS.NET id ac08902; 29 Jan 88 14:45 EST
Received: from csc.ti.com by RELAY.CS.NET id ai06767; 29 Jan 88 14:29 EST
Received: from Jenner by tilde id AA03005; Fri, 29 Jan 88 12:34:53 CST
Message-Id: <2779468561-913565@Jenner>
Date: Fri, 29 Jan 88 12:36:01 CST
From: Patrick H Dussud <DUSSUD@jenner.csc.ti.com>
To: common-lisp-object-system@SAIL.STANFORD.EDU
Subject: Re: class updating protocol
In-Reply-To: Msg of 29 Jan 88 09:23 PST from Danny Bobrow <Bobrow.pa@xerox.com>
Date: 29 Jan 88 09:23 PST
From: Danny Bobrow <Bobrow.pa@xerox.com>
Subject: Re: class updating protocol
Does update-dependent call update-dependent on its dependents,
or is the dependent structure flat? This probably needs to be
specified.
The intent was that update-dependent would flat. Of course, if the way a
particlar method on update-dependent works is to call reinitinaize-instance then
...
Why does finalize-inheritance have to do its work by calling
(UPDATE-DEPENDENT class class)? It seems backward to me. Why can't
UPDATE-DEPENDENT call (FINALIZE-INHERITANCE dependent), and
FINALIZE-INHERITANCE do the slot and CPL computation?
Because finalize-inheritance is defined to do nothing after the first time that
inheritance is finalized. This is to avoid having redundant calls to
finalize-inheritance recompute each time.
I understand that, but why does finalize-inheritance have to be called
redundantly? the code that calls it can check the status of the class
before. This seems cleaner.
Patrick.
∂29-Jan-88 1903 Common-Lisp-Object-System-mailer Re: Comments on latest draft documents
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 29 Jan 88 19:03:20 PST
Received: from Cabernet.ms by ArpaGateway.ms ; 29 JAN 88 19:01:36 PST
Date: 29 Jan 88 19:01 PST
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Re: Comments on latest draft documents
In-reply-to: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>'s message of
Fri, 29 Jan 88 14:06 EST
To: Moon@STONY-BROOK.SCRC.Symbolics.COM
cc: LGD@SAIL.STANFORD.EDU, Common-Lisp-Object-System@SAIL.STANFORD.EDU
Message-ID: <880129-190136-2313@Xerox>
I don't think anything was decided. My point is that it's
silly, in my opinion, to use parameter specializers on new-value
arguments to setf methods as a way of doing type-checking (rather
than specialization), and more importantly that I don't think the
CLOS specification should imply that if you need to store a
different type of value, you have to define your own method. I
suppose this comes down to the issue of what is the contract of the
method and what is the contract of the generic function, again.
Since we agreed not to try to solve that in chapter 2 this time
around, I would be happier if the method signatures didn't
specialize the new-value arguments.
I agree with this point. I think that in general it is a bad way of doing
business to specialize arguments in CLOS just for type checking purposes. It
implies that there might be other specializations, not that some of the
arguments determine the type for the rest of the arguments.
If anyone wants to argue for or against the class-name function
being restricted by the CLOS specification to return only symbols,
this is the place to speak up about it.
I would strongly prefer not to put this restriction on class-name at this time.
∂30-Jan-88 0955 Common-Lisp-Object-System-mailer Remarks about Comments on Latest Draft Documents
To: common-lisp-object-system@SAIL.Stanford.EDU
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>
The name of a class is restricted to be a symbol in chapter 1, and that
text has been there for a long time. That restriction appears in the
paragraph about proper names. As you recall, that paragraph was discussed
at great length in person and by netmail during rounds of review of the
chapters earlier this fall. Apparently no one thought to criticize the
restriction at that point.
The restriction and the implementation of the restriction are two
different topics.
I believe the restriction is fine, and I am also perturbed that
sections of the specification that have been reviewed extensively
are often subject to later changes. At some point we need to
decide that something is final so that the entire document can be
made consistent. Linda was simply trying to make the descriptions in
chapter 2 coincide with statements in chapter 1.
At this point I believe that compelling arguments must be made for even
small changes. There is no tradition of using non-symbols for names in
Lisp. Non-symbols are used as keys for various purposes, but not as names.
Defstruct restricts names to symbols. Therefore, I can see no compelling
reason to break the tradition and allow non-symbols to be the names of
classes.
I do not find silly the use of parameter specializers to do typechecking.
I find it hard to imagine what sort of argument one could make to show
that point of view. That issue is different from the one about whether we
ought to use parameter specializers in the document for that purpose. On
this point I suppose it is better to simply state the restrictions in
English in the remarks. Therefore, I suggest that chapter 2 reflect
chapter 1 on this point in the remarks. saying that the parameter
specializer for the new value is T.
On the topic of the DOCUMENTATION generic function, my opinion is that the
remarks ought to state in English the restriction that the new value in a
SETF of DOCUMENTATION must be a string or it must be NIL to signify that
the association between any existing documentation and the object in
question must be eliminated. This restriction is stronger than any that
can be conservatively deduced from CLtL, though it is not stronger can be
reasonably deduced.
The following reasoning was stated against this restriction:
CLtL doesn't say anywhere what values are allowed, but a
reasonable inference is that NIL is allowed, and "documentation
information" might have been meant to include some sort of
structures as well.
CLtL states four times that strings are the things that are associated
with symbols as documentation. It never states that anything else can be
associated with symbols as documentation. CLtL does state that the
function DOCUMENTATION will return NIL if no documentation exists. The
statement ``SETF may be used with DOCUMENTATION to update documentation
information'' in the context of the documentation section and the section
on SETF does not imply anything about the types of new values, but it
similarly does not imply anything about the nature of the update except
that whatever happens, DOCUMENTATION returns a string or NIL. So if a
structure is given as the new value in a SETF expression, DOCUMENTATION
will return a string or NIL - one cannot be sure that if it returns a
string that the string is related to the structure.
It is reasonable to conclude that NIL can be given to SETF of DOCUMENTATION,
but the reasonable conclusion about the effect of this is to remove any
association between an existing documentation string and the symbol.
I therefore favor introducing the restriction.
-rpg-
∂30-Jan-88 2128 Common-Lisp-Object-System-mailer Chapter 1
To: common-lisp-object-system@SAIL.Stanford.EDU
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>
There are new CONCEP.TEX and CONCEP.DVI on [CLS,LSP] at SAIL.
This ought to be the next to the last version.
-rpg-
∂31-Jan-88 1622 Common-Lisp-Object-System-mailer Chapter 2
To: common-lisp-object-system@SAIL.Stanford.EDU
From: Linda DeMichiel <LGD@SAIL.Stanford.EDU>
New FUNCTI.TEX and FUNCTI.DVI files are available on [CLS,LSP] at SAIL.
-lgd
∂01-Feb-88 1457 Common-Lisp-Object-System-mailer Re: Remarks about Comments on Latest Draft Documents
Received: from RELAY.CS.NET by SAIL.Stanford.EDU with TCP; 1 Feb 88 14:57:11 PST
Received: from relay2.cs.net by RELAY.CS.NET id ag26311; 1 Feb 88 14:31 EST
Received: from csc.ti.com by RELAY.CS.NET id al26097; 1 Feb 88 14:17 EST
Received: from Jenner by tilde id AA08087; Mon, 1 Feb 88 12:49:18 CST
Message-Id: <2779728586-434545@Jenner>
Date: Mon, 1 Feb 88 12:49:46 CST
From: Patrick H Dussud <DUSSUD@jenner.csc.ti.com>
To: common-lisp-object-system@SAIL.STANFORD.EDU
Subject: Re: Remarks about Comments on Latest Draft Documents
In-Reply-To: Msg of 30 Jan 88 0955 PST from Dick Gabriel <RPG@sail.stanford.edu>
At this point I believe that compelling arguments must be made for even
small changes. There is no tradition of using non-symbols for names in
Lisp.
Actually there is, function specs are an example of this. The
motivation for non symbol names in CLOS comes from the fact that we can
deal with first class objects. Naming can be seen as a reflection of
the access path to the object. Some implementations may arrange this
name so it can be used for reading as well. I don't propose that we
adopt anything like that, I am saying that the motivation is there. I
wouldn't like that we explicitly disallow non symbol names.
Patrick.
∂02-Feb-88 1032 Common-Lisp-Object-System-mailer Comments on most recent draft: Chap 1 and 2
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 2 Feb 88 10:32:01 PST
Received: from Cabernet.ms by ArpaGateway.ms ; 02 FEB 88 10:16:38 PST
Date: 2 Feb 88 10:16 PST
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Comments on most recent draft: Chap 1 and 2
To: common-lisp-object-system@SAIL.Stanford.EDU
Message-ID: <880202-101638-2198@Xerox>
CHAPTER 1
page 8:
We have discussed extensively why we should not force a restriction on the value
of class-name. The following text would reflect the looser condition.
A class can have a name. The function class-name takes a class object and
returns its name. The name of an anonymous class is nil. All the names used in
this specification are symbols, though we place no restriction of the type of a
name. Two names are the same if they are eql. The function symbol-class takes
a name and returns the class associated with that name, or nil if there is none.
p 1-20 There is a paragraph "Each class that corresponds to a predefined ..."
which is a good specification of how Common Lisp classes may be implemented.
Can we remove the paragraph "The Object System specifes that all predefined ..."
which confuses the issue.
At the bottom, it does not specify if make-instance can be used for objects
defined by defstruct. We should say one way or the other.
p 1-30
Rule 5 is incorrect as it stands. It is described corrctly in the text later on
the page. This rule could be rephrased as:
"If &allow-other-keys is mentioned in the lambda-list of a method, then that
method is applicable, any keyword argument may be mentioned in the call to this
generic function."
p1-48 Shouldn't it say in this section that we
are depending on an extension to Common Lisp to allow
(symbol-function '(setf foo))
to return the corresponding function object.
CHAPTER 2
p2-8
The method signature should use method instead of standard-method. Moon has
argued that standard-accessor-method should be disjoint from standard-method. I
pointed out some differences in behavior that would require negative inheritance
if they are not disjoint. But both need to be able to be added to generic
functions.
P 2-17 class-name
To correspond to the class-name change, remove the phrase "this result is a
symbol."
p2-19
To go along with the change to class-name
"The function cmakunbound causes the given name to no longer refer to a class in
the given environment; that is, (symbol-class name env) will now return nil for
that name."
And replace "symbol" by "name" in Syntax and Remarks.
p2-28 Remarks spells out a number of cases for replacement and retention of
methods, but omits the case where there are methods on an existing generic
function, and there are method descriptions which do not overlap entirely. This
paragraph might read:
"If a generic function with the same name already exists, all methods on that
generic function are retained, or replaced by a corresponding method specified
in a method description. A method description corresponds to an existing method
if it has the same parameter specializers and the same qualifiers. New methods
are added to the generic function for method descriptions which do not
correspond to any existing methods."
p2-52
The description makes it clear that the default value of errorp is t. Shouldn't
that be reflected in the method signature?
EXCEPTION CONDITION HANDLERS
Generic functions for handling exception conditions are defined in order to
allow users to specialize their behavior. They only signal an error. Hence
they ought have a method signature with no specialization. Moon made that point
in an earlier message. Thus:
p 2-64
no-applicable-method (generic-function t) &rest function-arguments
This allows a programming environment (or a delegation hacker) to define the
behavior for standard-generic-function without having to remove the system
defined method (which under certain circumstances may still want to be invoked
with call-next-method).
Similarly
p 2-71
slot-missing (class t) object slot-name operation &optional new-value
It needs to say below that "the default method signals an error"
and
p 2-72
slot-unbound (class t) instance slot-name
It needs to say below that "the default method signals an error"
p 2-74
symbol-class
The occurences of symbol should be replaced by name.
∂02-Feb-88 1401 Common-Lisp-Object-System-mailer Class Names (Again! Can't We Ever Stop?)
To: common-lisp-object-system@SAIL.Stanford.EDU
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>
rpg: ``There is no tradition of using non-symbols for names in Lisp.''
Dussud:
``Actually there is, function specs are an example of this. The
motivation for non symbol names in CLOS comes from the fact that we can
deal with first class objects. ''
This is part of a newly emerging tradition - that is, it's the latest
thing as far as Common Lisp is concerned. It might be a tradition in Lisp
machine Lisp, and in fact we adopted a reduced function specification notion
for functions in the form of setf generic functions. This has nothing to
do with the names of classes, which is the issue. If we generalize from
function names to class names, why not continue on to slot names?
Why restrict instances to look like structures? Why have slots?
The topic of naming objects in CLOS is addressed by an entire level of the
meta-object protocol. I see no reason to introduce gratuitous and unmotivated
generalizations into the base level when someone who wants to introduce a
bizarre naming scheme will have all the mechanism laid at his feet with
which to do it.
Here is the compelling reason for restricting class names: It introduces
a bit of generality for which very few people will imagine a use, and while
doing so it increases the complexity of an already too-complex specification
that already has mechanisms to handle naming. In short: epsilon complexity
increase, zero benefit.
-rpg-
∂02-Feb-88 1818 Common-Lisp-Object-System-mailer Re: Class Names (Again! Can't We Ever Stop?)
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 2 Feb 88 18:17:49 PST
Received: from Cabernet.ms by ArpaGateway.ms ; 02 FEB 88 17:59:48 PST
Date: 2 Feb 88 17:57 PST
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Re: Class Names (Again! Can't We Ever Stop?)
In-reply-to: Dick Gabriel <RPG@SAIL.Stanford.EDU>'s message of 02 Feb 88 14:01
PST
To: RPG@SAIL.Stanford.EDU
cc: common-lisp-object-system@SAIL.Stanford.EDU
Message-ID: <880202-175948-1439@Xerox>
The topic of naming objects in CLOS is addressed by an entire
level of the meta-object protocol. I see no reason to introduce
gratuitous and unmotivated generalizations into the base level when
someone who wants to introduce a bizarre naming scheme will have
all the mechanism laid at his feet with which to do it.
There is no mechanism to handle names for classes specified in the metaobject
protocol other than symbol-class and class-name. It is for this reason that one
wants not to restrict the values of class-names.
It introduces a bit of generality for which very few people
will imagine a use, and while doing so it increases the complexity
of an already too-complex specification that already has mechanisms
to handle naming. In short: epsilon complexity increase, zero
benefit.
This removes a restriction rather than introducing a generality. The only
property of symbols that is used, as far as I can see, is the ease of typing
something in that will be EQL each time. With the EQL restriction on how names
refer to classes, I see neither an implementation problem nor a conceptual one.
Those users who can never think of a use for this feature will never have to
encounter it (it never interferes). We have used this feature extensively for
dynamically constructed class combinations, with mixins selected from carefully
selected orthogonal sets, where to have to have a symbol for a name causes
construction of long ugly concatenations.
danny
∂02-Feb-88 2040 Common-Lisp-Object-System-mailer Names, Names
To: Common-Lisp-object-system@SAIL.Stanford.EDU
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>
Danny:
``There is no mechanism to handle names for classes specified in the metaobject
protocol other than symbol-class and class-name.''
If non-symbols can be names, I'd say there had better be such a mechanism.
-rpg-
∂03-Feb-88 0757 Common-Lisp-Object-System-mailer Chapter 1
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 3 Feb 88 07:57:11 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 334293; Tue 2-Feb-88 21:50:39 EST
Date: Tue, 2 Feb 88 21:50 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Chapter 1
To: common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: The message of 31 Jan 88 00:28 EST from Dick Gabriel <RPG@SAIL.Stanford.EDU>
Message-ID: <19880203025029.0.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: 30 Jan 88 2128 PST
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>
There are new CONCEP.TEX and CONCEP.DVI on [CLS,LSP] at SAIL.
This ought to be the next to the last version.
The changes that were made up to Monday evening, when I last copied the
file, are fine. I didn't check whether every change that I thought
should be made, had been made.
∂03-Feb-88 0757 Common-Lisp-Object-System-mailer Chapter 2
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 3 Feb 88 07:57:31 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 334295; Tue 2-Feb-88 21:59:55 EST
Date: Tue, 2 Feb 88 21:59 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Chapter 2
To: common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: The message of 31 Jan 88 19:22 EST from Linda DeMichiel <LGD@SAIL.Stanford.EDU>
Message-ID: <19880203025952.1.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: 31 Jan 88 1622 PST
From: Linda DeMichiel <LGD@SAIL.Stanford.EDU>
New FUNCTI.TEX and FUNCTI.DVI files are available on [CLS,LSP] at SAIL.
The changes that were made up to Monday evening, when I last copied the
file, are fine. I didn't check whether every change that I thought
should be made, had been made, except to note that the removal of
make-method-call and addition of call-method and make-method still
needs to be done.
∂03-Feb-88 1022 Common-Lisp-Object-System-mailer Re: Names, Names
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 3 Feb 88 10:22:38 PST
Received: from Cabernet.ms by ArpaGateway.ms ; 03 FEB 88 10:20:25 PST
Date: 3 Feb 88 10:19 PST
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Re: Names, Names
In-reply-to: Dick Gabriel <RPG@SAIL.Stanford.EDU>'s message of 02 Feb 88 20:40
PST
To: RPG@SAIL.Stanford.EDU
cc: Common-Lisp-object-system@SAIL.Stanford.EDU
Message-ID: <880203-102025-2482@Xerox>
Danny:
``There is no mechanism to handle names for classes specified
in the metaobject protocol other than symbol-class and class-name.''
If non-symbols can be names, I'd say there had better be such a
mechanism.
-rpg-
Not if the criterion is that symbol-class does an eql look-up, and class-name is
insensitive to type. Then ordinary users can write a structure to eql intern
for any structure they care to use, and use symbol-class to find the associated
class. Thus for the dynamic-class application I mentioned:
(defun get-dynamic-class (class-name-list)
(let((pair (assoc class-name-list *dynamic-classes* :test #'equal)))
(if pair
(symbol-class (cdr pair))
(let((new-class
(make-instance 'standard-class
:direct-superclasses (mapcar #'symbol-class class-name-list)
:direct-slots nil)))
;;; make class-name-list be proper name of new-class
(setf (class-name new-class) class-name-list)
(setf (symbol-class class-name-list) new-class)
(setf (assoc class-name-list *dynamic-classes*) class-name-list)
new-class))))
∂03-Feb-88 1449 Common-Lisp-Object-System-mailer Re: Names, Names
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 3 Feb 88 14:49:17 PST
Received: from Semillon.ms by ArpaGateway.ms ; 03 FEB 88 14:34:25 PST
Date: Wed, 3 Feb 88 14:34:06 PST
From: Ken Kahn <Kahn.pa@Xerox.COM>
Subject: Re: Names, Names
In-Reply-To: <880203-102025-2482@Xerox>
To: Danny Bobrow <Bobrow.pa@Xerox.COM>
cc: RPG@SAIL.Stanford.EDU, Common-Lisp-object-system@SAIL.Stanford.EDU
Message-ID: <880203-143425-3082@Xerox>
> Not if the criterion is that symbol-class does an eql look-up, and class-name
> is insensitive to type. Then ordinary users can write a structure to
> eql intern for any structure they care to use, and use symbol-class to
> find the associated class.
If you do this, then I suggest you rename symbol-class.
References
Bobrow's message of Wed, 3 Feb 88 10:19:00 PST -- Re: Names, Names
∂03-Feb-88 1532 Common-Lisp-Object-System-mailer Comments on most recent draft: Chap 1 and 2
Received: from labrea.Stanford.EDU by SAIL.Stanford.EDU with TCP; 3 Feb 88 15:32:09 PST
Received: by labrea.Stanford.EDU; Wed, 3 Feb 88 15:32:23 PST
Received: from bhopal.lucid.com by edsel id AA01307g; Wed, 3 Feb 88 14:33:40 PST
Received: by bhopal id AA11606g; Wed, 3 Feb 88 14:37:51 PST
Date: Wed, 3 Feb 88 14:37:51 PST
From: Jon L White <edsel!jonl@labrea.Stanford.EDU>
Message-Id: <8802032237.AA11606@bhopal.lucid.com>
To: labrea!Bobrow.pa%Xerox.COM@labrea.Stanford.EDU
Cc: labrea!common-lisp-object-system%SAIL@labrea.Stanford.EDU
In-Reply-To: Danny Bobrow's message of 2 Feb 88 10:16 PST <880202-101638-2198@Xerox>
Subject: Comments on most recent draft: Chap 1 and 2
re: . . . Two names are the same if they are eql. The function symbol-class
takes a name and returns the class associated with that name, or nil if
there is none.
X3J13 may take on the task of extending the naming schemes (such as
"function specs', but possibly something else), so you probably wouldn't
want to specify something in CLOS that would be at variance with that.
In that light, I would say that requiring EQL for the name-equivalence
predicate is a bad idea; EQUAL or something broader may be better. Best
of all would be to avoid any unnecessary entanglements in CLOS for now
by just not specifying what isn't really needed.
Also, isn't it true that SYMBOL-CLASS only takes a symbol, not a
"generalized" name? (In the broader sense, a better name for this
functionality might be FIND-CLASS). At any rate, using a name like
SYMBOL-CLASS, which implies parallels to SYMBOL-VALUE and SYMBOL-FUNCTION,
and overgeneralizing it to whatever nomenclature scheme comes up seems
like a real misdirection.
Incidentally, having *no* name for a class (I'm not talking about symbols
as names) makes it hard to talk about a type specifier that refers to that
class. Is is really so bad that anonymous classes can't be named in
type specifiers? if they can't be named at all (i.e., "has no name")
then why should the conventions for type names be changed?
-- JonL --
∂03-Feb-88 1822 Common-Lisp-Object-System-mailer Re: Comments on most recent draft: Chap 1 and 2
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 3 Feb 88 18:22:36 PST
Received: from Cabernet.ms by ArpaGateway.ms ; 03 FEB 88 18:23:09 PST
Date: 3 Feb 88 18:22 PST
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Re: Comments on most recent draft: Chap 1 and 2
In-reply-to: Jon L White <edsel!jonl@labrea.Stanford.EDU>'s message of Wed, 3
Feb 88 14:37:51 PST
To: edsel!jonl@labrea.Stanford.EDU
cc: Common-Lisp-Object-System@Sail.stanford.edu
Message-ID: <880203-182309-3472@Xerox>
X3J13 may take on the task of extending the naming schemes
(such as "function specs', but possibly something else), so you
probably wouldn't want to specify something in CLOS that would be
at variance with that. In that light, I would say that
requiring EQL for the name-equivalence predicate is a bad idea;
EQUAL or something broader may be better. Best of all would be to
avoid any unnecessary entanglements in CLOS for now by just not
specifying what isn't really needed.
I would be happy with this. Would this take the form of not saying what happens
for
(symbol-class foo) and (setf (symbol-class foo) bar)
when foo is not a symbol. Should it say that:
"CLOS may be extended to cover situations in which foo is not a symbol."
Similarly for class-name. I would be happy to use the "extended" clause for
symbol-class, and simply not say anything about class-name.
But, haven't we already extended symbol-function to take lists of the form (setf
fn) as an argument. If not, how do we get hold of setf generic-functions?
∂03-Feb-88 2235 Common-Lisp-Object-System-mailer Names
To: common-lisp-object-system@SAIL.Stanford.EDU
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>
If you don't think there is any reason to want to discriminate against
non-symbols as names, then why call the function SYMBOL-CLASS? Why not
name it NAME-CLASS? Then X is a proper name if (CLASS-NAME <class>) = X and
(NAME-CLASS X) = <class>.
If you do this, isn't there some other functionailty you'd like to specify
about names, like associating a name with an object, like registering
names (default, intern), mapping over them (default, do-symbols),
destroying them (default, ???)...?
If you go beyond function specs into the realm of class names, what about
the other naming contexts in Common Lisp: types, variables...?
If you eliminate SYMBOL-CLASS and use NAME-CLASS, are implementations free
to use SYMBOL-VALUE to implement NAME-CLASS? Or is there also the thing
meant by the old SYMBOL-CLASS that is used when symbols are specified as
the names? Does this mean that NAME-CLASS must be a generic function?
Chapters 1 and 2 specify a possible world as implementable by chapter 3.
mechanisms. By selecting that world we eliminate possibilities from it.
This doesn't mean that an adjacent world cannot be different. I don't
feel that we have considered enough of the can of worms opened by general
naming to want to casually introduce it into our nice little world.
-rpg-
∂04-Feb-88 1530 Common-Lisp-Object-System-mailer Comments on most recent draft: Chap 1 and 2
Received: from labrea.Stanford.EDU by SAIL.Stanford.EDU with TCP; 4 Feb 88 15:30:43 PST
Received: by labrea.Stanford.EDU; Thu, 4 Feb 88 15:31:02 PST
Received: from bhopal.lucid.com by edsel id AA09098g; Thu, 4 Feb 88 14:42:19 PST
Received: by bhopal id AA01035g; Thu, 4 Feb 88 14:46:35 PST
Date: Thu, 4 Feb 88 14:46:35 PST
From: Jon L White <edsel!jonl@labrea.Stanford.EDU>
Message-Id: <8802042246.AA01035@bhopal.lucid.com>
To: labrea!Bobrow.pa%Xerox.COM@labrea.Stanford.EDU
Cc: labrea!Common-Lisp-Object-System%Sail@labrea.Stanford.EDU
In-Reply-To: Danny Bobrow's message of 3 Feb 88 18:22 PST <880203-182309-3472@Xerox>
Subject: Comments on most recent draft: Chap 1 and 2
re: . . . Should it say that:
"CLOS may be extended to cover situations in which foo is not a symbol."
Very good. I think that is the preferred wording, given that page of
chapter 1 about error conditions etc.
re: But, haven't we already extended symbol-function to take lists of the
form (setf fn) as an argument. If not, how do we get hold of setf
generic-functions?
I don't recall how the recent discussions on this mailing list suggested
to do it. A reasonable user-extensible naming scheme, such as Interlisp's
"typed definitions" system or the LispMachine's function specs, would have
form-specific ways to access the created definitions. That is, when you
defined (setf fn) to be a "function spec" or whatever, you would provide
creator, accessor, (and possibly) modifer functions.
-- JonL --
∂04-Feb-88 1631 Common-Lisp-Object-System-mailer Naming
To: common-lisp-object-system@SAIL.Stanford.EDU
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>
We need to decide by the end of the weekend what to do about naming.
I strongly hesitate to make the change (if it can be said that one can
strongly hesitate). If we make the change I prefer the terms NAME-<word>
over SYMBOL-<word>. I worry that we will make an ugly mistake in doing
this.
-rpg-
∂04-Feb-88 1653 Common-Lisp-Object-System-mailer Re: Naming
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 4 Feb 88 16:53:46 PST
Received: from Cabernet.ms by ArpaGateway.ms ; 04 FEB 88 16:54:04 PST
Date: 4 Feb 88 16:53 PST
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Re: Naming
In-reply-to: Dick Gabriel <RPG@SAIL.Stanford.EDU>'s message of 04 Feb 88 16:31
PST
To: RPG@SAIL.Stanford.EDU
cc: common-lisp-object-system@SAIL.Stanford.EDU
Message-ID: <880204-165404-1377@Xerox>
We need to decide by the end of the weekend what to do about
naming. I strongly hesitate to make the change (if it can be said
that one can strongly hesitate). If we make the change I prefer the
terms NAME-<word> over SYMBOL-<word>. I worry that we will make an
ugly mistake in doing this.
To avoid such ugliness, let us leave symbol-class and (setf symbol-class) with a
restriction to symbols.
However, let us take out any restriction about what can be stored/returned from
class-name. Then the dynamic-class hack can work using its own class lookup
mechanism, and class-name can contain the hint about what the class is.
∂04-Feb-88 1714 Common-Lisp-Object-System-mailer Re: Naming
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 4 Feb 88 17:14:39 PST
Received: from Semillon.ms by ArpaGateway.ms ; 04 FEB 88 17:15:06 PST
Date: Thu, 4 Feb 88 17:14 PST
From: Gregor.pa@Xerox.COM
Subject: Re: Naming
To: Danny Bobrow <Bobrow.pa@Xerox.COM>
cc: RPG@SAIL.STANFORD.EDU, common-lisp-object-system@SAIL.STANFORD.EDU
Fcc: BD:>Gregor>mail>outgoing-mail-1.text
In-Reply-To: <880204-165404-1377@Xerox>
Message-ID: <880204171452.7.GREGOR@SPIFF.parc.xerox.com>
Line-fold: no
Date: 4 Feb 88 16:53 PST
From: Danny Bobrow <Bobrow.pa>
We need to decide by the end of the weekend what to do about
naming. I strongly hesitate to make the change (if it can be said
that one can strongly hesitate). If we make the change I prefer the
terms NAME-<word> over SYMBOL-<word>. I worry that we will make an
ugly mistake in doing this.
To avoid such ugliness, let us leave symbol-class and (setf symbol-class) with a
restriction to symbols.
However, let us take out any restriction about what can be stored/returned from
class-name. Then the dynamic-class hack can work using its own class lookup
mechanism, and class-name can contain the hint about what the class is.
Right.
-------
∂05-Feb-88 0839 Common-Lisp-Object-System-mailer Re: Naming
Received: from RELAY.CS.NET by SAIL.Stanford.EDU with TCP; 5 Feb 88 08:39:03 PST
Received: from relay2.cs.net by RELAY.CS.NET id aa20259; 5 Feb 88 11:00 EST
Received: from csc.ti.com by RELAY.CS.NET id ac00992; 5 Feb 88 10:52 EST
Received: from Jenner by tilde id AA21556; Fri, 5 Feb 88 07:23:59 CST
Message-Id: <2780054729-2276568@Jenner>
Date: Fri, 5 Feb 88 07:25:29 CST
From: Patrick H Dussud <DUSSUD@jenner.csc.ti.com>
To: Danny Bobrow <Bobrow.pa@XEROX.COM>
Cc: common-lisp-object-system@SAIL.STANFORD.EDU
Subject: Re: Naming
In-Reply-To: Msg of 4 Feb 88 16:53 PST from Danny Bobrow <Bobrow.pa@xerox.com>
We need to decide by the end of the weekend what to do about
naming. I strongly hesitate to make the change (if it can be said
that one can strongly hesitate). If we make the change I prefer the
terms NAME-<word> over SYMBOL-<word>. I worry that we will make an
ugly mistake in doing this.
To avoid such ugliness, let us leave symbol-class and (setf symbol-class) with a
restriction to symbols.
However, let us take out any restriction about what can be stored/returned from
class-name.
I agree.
Patrick.
∂05-Feb-88 0948 Common-Lisp-Object-System-mailer CONCEP and FUNCTI
To: common-lisp-object-system@SAIL.Stanford.EDU
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>
There are new CONCEP and FUNCTI .TEX and .DVI files on SAIL. These
incorporate Danny's comments and the infamous (class-name <class>) = junk
change. The impact of this latter change is minimal because many things
deal with proper names, which are still symbols. For example, defclass
and parameter specializers all either define proper names or take
symbols as the names of classes. We hope to send these two chapters
to X3J13 monday.
-rpg-
∂05-Feb-88 1042 Common-Lisp-Object-System-mailer Re: Naming
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 5 Feb 88 10:42:34 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 336852; Fri 5-Feb-88 13:42:36 EST
Date: Fri, 5 Feb 88 13:42 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: Naming
To: common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: <880204-165404-1377@Xerox>
Message-ID: <19880205184244.7.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: 4 Feb 88 16:53 PST
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
We need to decide by the end of the weekend what to do about
naming. I strongly hesitate to make the change (if it can be said
that one can strongly hesitate). If we make the change I prefer the
terms NAME-<word> over SYMBOL-<word>. I worry that we will make an
ugly mistake in doing this.
To avoid such ugliness, let us leave symbol-class and (setf symbol-class) with a
restriction to symbols.
However, let us take out any restriction about what can be stored/returned from
class-name. Then the dynamic-class hack can work using its own class lookup
mechanism, and class-name can contain the hint about what the class is.
Yes. Only a symbol can be a proper name, and non-symbol values for
class-name are only hints. In a discussion last fall (I think), we had
already decided that class-name was a hint, and wasn't necessarily
always the proper name.
What Danny is proposing here is what I thought all along I was
proposing, however I was too distracted to produce a coherent wording.
I apologize for the digression, and thank Danny for bringing us back to
earth. I never meant to propose some elaborate new naming scheme, only
to propose that the hints returned by class-name need not be symbols.
∂05-Feb-88 1048 Common-Lisp-Object-System-mailer Re: Naming
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 5 Feb 88 10:48:12 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via INTERNET with SMTP id 336862; 5 Feb 88 13:48:14 EST
Date: Fri, 5 Feb 88 13:48 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: Naming
To: common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: <880204-165404-1377@Xerox>
Supersedes: <19880205184244.7.MOON@EUPHRATES.SCRC.Symbolics.COM>
Comments: Added a note in response to "At this point I believe that compelling
arguments must be made for even small changes."
Message-ID: <19880205184818.8.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: 4 Feb 88 16:53 PST
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
We need to decide by the end of the weekend what to do about
naming. I strongly hesitate to make the change (if it can be said
that one can strongly hesitate). If we make the change I prefer the
terms NAME-<word> over SYMBOL-<word>. I worry that we will make an
ugly mistake in doing this.
To avoid such ugliness, let us leave symbol-class and (setf symbol-class) with a
restriction to symbols.
However, let us take out any restriction about what can be stored/returned from
class-name. Then the dynamic-class hack can work using its own class lookup
mechanism, and class-name can contain the hint about what the class is.
Yes. Only a symbol can be a proper name, and non-symbol values for
class-name are only hints. In a discussion last fall (I think), we had
already decided that class-name was a hint, and wasn't necessarily
always the proper name.
What Danny is proposing here is what I thought all along I was
proposing, however I was too distracted to produce a coherent wording.
I apologize for the digression, and thank Danny for bringing us back to
earth. I never meant to propose some elaborate new naming scheme, only
to propose that the hints returned by class-name need not be symbols.
By the way, I don't think this is a change. I think class-name was not
restricted in type up until recently when as a side-effect of making the
document clearer and more specific, a type restriction was put in by
accident. So we're just saying that that was an accident, rather than
an intention, and hence should be undone before publication.
∂05-Feb-88 1101 Common-Lisp-Object-System-mailer Re: Type-checking of slot values
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 5 Feb 88 11:01:25 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 336877; Fri 5-Feb-88 13:59:14 EST
Date: Fri, 5 Feb 88 13:59 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: Type-checking of slot values
To: kempf%hplabsz@hplabs.HP.COM
cc: Jon L White <edsel!jonl@labrea.Stanford.EDU>, common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: <352.570317112@hplabsz>
Message-ID: <19880205185920.0.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Wed, 27 Jan 88 13:25:12 PST
From: kempf%hplabsz@hplabs.HP.COM
I had, at one time,
proposed a set of primitives to freeze the class structure about a certain
class, but there appeared to be little or no interest in this idea, and it
somehow got dropped. This would allow an instance implementation with one level
of indirection, but attempts to change the class would signal an error.
I'm interested in this, and think it should not be dropped. I'm just not
interested in personally contributing to writing it up, since I have no
expertise in this area and plenty of other things to do instead. I'd
like to encourage you to keep pursuing it.
∂05-Feb-88 1140 Common-Lisp-Object-System-mailer Typechecking
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 5 Feb 88 11:40:49 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 336904; Fri 5-Feb-88 14:40:48 EST
Date: Fri, 5 Feb 88 14:40 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Typechecking
To: Common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: The message of 28 Jan 88 00:28 EST from Dick Gabriel <RPG@SAIL.Stanford.EDU>
Message-ID: <19880205194056.1.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: 27 Jan 88 2128 PST
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>
I think Moon must have gotten a bad chapter 1, because I cannot find the
quote he mentions in the file that I consider to be the definitive version.
It's there, and you quoted it yourself. You were just misled because I
extracted part of a sentence without putting in ellipses. But let's
forget that. The important quote is "Attempting to store a value in a
slot that does not satisfy the type should signal an error", as you
pointed out. I never should have drawn attention to the later quote
which is just amplifying on this.
Chapter 1 defines "should signal an error" to mean "an error will be
signaled at least in the interpreter and in code compiled under the
safest compiler safety optimization level." I still object to what
chapter 1 currently says about the :type slot option. To rephrase what
I said before:
Sometime between August and November the definition of the :type slot
option was changed from "An implementation may or may not choose to
check the type of the new value when initializing or assigning to a
slot" to "Attempting to store a value in a slot that does not satisfy
the type should signal an error". It is not consistent with CLtL's
definition of the :type slot option in defstruct and the type
declaration for variables. Violation of those type constraints "is an
error" according to CLtL.
The choices we have available to us are to require checking in all
cases, to require checking in at least the safest compiler compilation
setting and the interpreter, or to let the results be undefined. Stock
hardware people reject the first, and special-purpose people reject the last
(they want the results to be defined - to signal an error).
This "special-purpose person" does not -- I want type-checking of slot
values to be optional. I want the results to be undefined, as that
phrase is defined in the front of chapter 1. What I -really- want is
for CLOS and the rest of Common Lisp to be consistent on this issue. As
long as the rest of Common Lisp continues to say that the results are
undefined, CLOS should say the same.
Therefore, it
has to be ``should signal an error.'' We agreed long ago to abide by this
error terminology, and I won't accept backing down on that now.
I don't object to the terminology for describing the semantics, only to
which semantics was chosen.
Is there anyone who actually wants "should signal an error" and won't
accept "results are undefined"? If not, let's change it. If so, that
person should be agitating to change Common Lisp as well.
∂05-Feb-88 1141 Common-Lisp-Object-System-mailer Typechecking
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 5 Feb 88 11:41:13 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 336905; Fri 5-Feb-88 14:41:17 EST
Date: Fri, 5 Feb 88 14:41 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Typechecking
To: Common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: The message of 28 Jan 88 00:28 EST from Dick Gabriel <RPG@SAIL.Stanford.EDU>
Supersedes: <19880205194056.1.MOON@EUPHRATES.SCRC.Symbolics.COM>
Message-ID: <19880205194124.2.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: 27 Jan 88 2128 PST
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>
I think Moon must have gotten a bad chapter 1, because I cannot find the
quote he mentions in the file that I consider to be the definitive version.
It's there, and you quoted it yourself. You were just misled because I
extracted part of a sentence without putting in ellipses. But let's
forget that. The important quote is "Attempting to store a value in a
slot that does not satisfy the type should signal an error", as you
pointed out. I never should have drawn attention to the later quote
which is just amplifying on this.
Chapter 1 defines "should signal an error" to mean "an error will be
signaled at least in the interpreter and in code compiled under the
safest compiler safety optimization level." I still object to what
chapter 1 currently says about the :type slot option. To rephrase what
I said before:
Sometime between August and November the definition of the :type slot
option was changed from "An implementation may or may not choose to
check the type of the new value when initializing or assigning to a
slot" to "Attempting to store a value in a slot that does not satisfy
the type should signal an error". It is not consistent with CLtL's
definition of the :type slot option in defstruct and the type
declaration for variables. Violation of those type constraints "is an
error" according to CLtL.
The choices we have available to us are to require checking in all
cases, to require checking in at least the safest compiler compilation
setting and the interpreter, or to let the results be undefined. Stock
hardware people reject the first, and special-purpose people reject the last
(they want the results to be defined - to signal an error).
This "special-purpose person" does not -- I want type-checking of slot
values to be optional. I want the results to be undefined, as that
phrase is defined in the front of chapter 1. What I -really- want is
for CLOS and the rest of Common Lisp to be consistent on this issue. As
long as the rest of Common Lisp continues to say that the results are
undefined, CLOS should say the same.
Therefore, it
has to be ``should signal an error.'' We agreed long ago to abide by this
error terminology, and I won't accept backing down on that now.
I don't object to the terminology for describing the semantics, only to
which semantics was chosen.
Is there anyone who actually wants "should signal an error" and won't
accept "results are undefined"? If so, that person should be agitating
to change Common Lisp as well. If not, let's change it (that is, let's
change it -back-).
∂05-Feb-88 1230 Common-Lisp-Object-System-mailer Typechecking
To: common-lisp-object-system@SAIL.Stanford.EDU
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>
Moon's message caused me to unwedge about what he was talking about. I am
happy to specify the behavior of CLOS when stores violate the :type option
as undefined. Do we have consensus?
-rpg-
∂05-Feb-88 1310 Common-Lisp-Object-System-mailer Re: Typechecking
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 5 Feb 88 13:10:08 PST
Received: from Cabernet.ms by ArpaGateway.ms ; 05 FEB 88 13:00:34 PST
Date: 5 Feb 88 13:00 PST
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Re: Typechecking
In-reply-to: Dick Gabriel <RPG@SAIL.Stanford.EDU>'s message of 05 Feb 88 12:30
PST
To: RPG@SAIL.Stanford.EDU
cc: common-lisp-object-system@SAIL.Stanford.EDU
Message-ID: <880205-130034-2896@Xerox>
Moon's message caused me to unwedge about what he was talking
about. I am happy to specify the behavior of CLOS when stores
violate the :type option as undefined. Do we have consensus?
-rpg-
Fine
danny
∂05-Feb-88 1334 Common-Lisp-Object-System-mailer defgeneric :method option
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 5 Feb 88 13:34:11 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 337094; Fri 5-Feb-88 16:34:14 EST
Date: Fri, 5 Feb 88 16:34 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: defgeneric :method option
To: Common-Lisp-Object-System@SAIL.STANFORD.EDU
In-Reply-To: <19880119164517.8.MOON@EUPHRATES.SCRC.Symbolics.COM>,
<19880119195151.1.MOON@EUPHRATES.SCRC.Symbolics.COM>,
<880119-154316-2487@Xerox>,
The message of 21 Jan 88 17:28 EST from Dick Gabriel <RPG@SAIL.Stanford.EDU>
Message-ID: <19880205213415.6.MOON@EUPHRATES.SCRC.Symbolics.COM>
This issue is still open: when a defgeneric is evaluated with a :method
option, and then evaluated again without the :method option, does the
method go away, reflecting the updated defgeneric, or does the method
stay around?
Date: Tue, 19 Jan 88 11:45 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
It wouldn't bother me a bit if we changed the language to require all
implementations to remove methods that were created by a defgeneric, if
the defgeneric were re-evaluated without the :method. We already do this
for accessor methods created by defclass. We're now saying that the class
remembers the specific method objects and removes them if they are still
there; if they've already been replaced by a defmethod, it doesn't remove
the method put there by the defmethod.
What would bother me would be if we required all implementations to be
stupid about this.
So how about it? Shall we change CLOS so that re-evaluating a defgeneric
removes methods that were previously defined by :method, but no longer
appear in the new defgeneric form? I think we should.
Date: Tue, 19 Jan 88 14:51 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Date: 19 Jan 88 09:37 PST
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
I think that's a good idea. Should we specify how defgeneric knows that a
method was defined by :method. We could use a predicate or we could make
:method specified methods be a subclass of defgeneric-method. This similar to
how accessors methods are specified, and is what I reecommend.
We decided at our last meeting that each class has a slot in which it
remembers a list of the defclass-defined methods.
Date: 19 Jan 88 15:40 PST
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
From: Moon
I think defgeneric should handle its specially-defined methods
in exactly the same way that defclass handles its.
I agree.
We decided at our last meeting that each class has a slot in
which it remembers a list of the defclass-defined methods. I'm not
imagining this, am I? I remember that idea winning out over giving
each method a slot that says how it was defined or having
defclass-defined methods be a special subclass.
I don't remember this, but my memory and notes are not to be trusted. Do you
remember any of the arguments for this decision. An argument against this is
that it implies that remove-method, and add-method that overrides must both be
cognizant of (side-effect) this list in this slot.
No, it doesn't imply that. The class remembers the method objects that
it added to the generic function. It's not required that if someone
else removes those method objects, they be removed from the class's
list. Instead, when the class uses its list, it checks whether each
method is still known by the generic function. This is what I remember
us concluding at our last meeting.
This works because Gregor argued down my idea that defmethod updates an
existing method object, instead of creating a new one that replaces any
previous one for the same generic function, specializers, and qualifiers.
Date: 21 Jan 88 1428 PST
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>
I think defgeneric should handle its specially-defined methods
in exactly the same way that defclass handles its.
I'm not sure what the specially-defined methods might be for a defgeneric.
All methods defined with the :method option.
My reading of the specification states that if some method descriptions
are supplied some methods are defined, but none of those are specially
defined in the manner that they are using defclass - in the defclass case
I suppose the specialness is tied up with the fact that they are
implicitly defined, though at the behest of the :reader, :writer, or
:accessor options. I notice no other methods mentioned.
The model currently stated is clear - defgeneric is semantically equivalent
to an ensure-generic-function and a series of defmethod's.
It's true that the model currently stated is clear. However, it has a
bad consequence, which is that evaluating a defgeneric form multiple
times has a different effect from evaluating the final version once.
None of CLOS's other defxxx forms have that property. I'm proposing to
change the model to a different model, which is also clear: defgeneric
is semantically equivalent to an ensure-generic-function, a series of
defmethod's whose values (method objects) are remembered, a series of
remove-method's of the remembered values from last time, and a setf to
remember the values for next time. This model certainly involves more
parts than the previous model, but that's not surprising. I don't
think there is anything unclear about it.
(progn
(ensure-generic-function 'name :blah blah blah)
(let ((methods (list (defmethod name blah blah blah)
(defmethod name blah blah blah)
...))
(generic (symbol-function 'name)))
(dolist (method (generic-function-locally-defined-methods generic))
(remove-method generic method))
(setf (generic-function-locally-defined-methods generic) methods)
generic))
I see no obvious
parallel with defclass. With defclass, the ``specially-defined'' methods are
so defined according to a strong convention that we have imposed - we would
all be surprised to see people write simple defclass forms and then a
series of defmethod's to build up the readers and writers.
Not at all. When I said exactly this, several months ago, someone (I think
it was Gregor) called me wedged and said that it was very important that the
user could just as well write reader and writer methods with defmethod and
get the same performance as when using the slot-option. The only difference
is that defgeneric lets you define any kind of method, whereas defclass
only lets you define some very specific, stereotyped methods.
But the
method-defining parts of defgeneric are for completeness only - we do
not advocate that people write method definitions within defgeneric forms.
If people do not like the fact that re-loading defgeneric forms doesn't
do what they want, then they can re-write them as simpler defgeneric's
and defmethod's, and they will be obeying classic object-oriented style
all the more if they do.
I really object to that. What you're saying is that we're going to document
this :method feature of defgeneric, but then we're going to tell them that
it doesn't work very well, so they shouldn't use it. In that case we would
be much better off removing it from the language entirely.
So I am against treating these methods in a manner analogous to
those defined by defclass.
Dick, I don't know if I have convinced you of anything in the above.
However, I have convinced myself of something. I no longer think that
the current state of CLOS is acceptable. To be an acceptable standard,
I now feel that we must either remove the :method feature from
defgeneric, or else we must make defgeneric remember the methods that it
defines and remove them when evaluated a second time. Either of those
alternatives would be acceptable to me, although naturally I prefer the
second since it makes defgeneric more consistent with generic-flet.
∂05-Feb-88 1936 Common-Lisp-Object-System-mailer Re: Typechecking
Received: from RELAY.CS.NET by SAIL.Stanford.EDU with TCP; 5 Feb 88 19:35:58 PST
Received: from relay2.cs.net by RELAY.CS.NET id ab27993; 5 Feb 88 19:39 EST
Received: from csc.ti.com by RELAY.CS.NET id ab05375; 5 Feb 88 19:32 EST
Received: from Jenner by tilde id AA03312; Fri, 5 Feb 88 16:41:13 CST
Message-Id: <2780084688-71255@Jenner>
Date: Fri, 5 Feb 88 15:44:48 CST
From: Patrick H Dussud <DUSSUD@jenner.csc.ti.com>
To: common-lisp-object-system@SAIL.STANFORD.EDU
Subject: Re: Typechecking
In-Reply-To: Msg of 05 Feb 88 1230 PST from Dick Gabriel <RPG@sail.stanford.edu>
Date: 05 Feb 88 1230 PST
From: Dick Gabriel <RPG@sail.stanford.edu>
Subject: Typechecking
Moon's message caused me to unwedge about what he was talking about. I am
happy to specify the behavior of CLOS when stores violate the :type option
as undefined. Do we have consensus?
I agree this.
Patrick.
∂05-Feb-88 2205 Common-Lisp-Object-System-mailer Defgeneric
To: common-lisp-object-system@SAIL.Stanford.EDU
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>
Moon writes:
``Dick, I don't know if I have convinced you of anything in the above.
However, I have convinced myself of something. I no longer think....''
It convinced me of something too: I no longer have an opinion about
what defgeneric does with old or new methods. I will attempt to write
down some description of what you propose and place it in the document.
I don't believe that the activities of defclass in this regard are
accurately stated either. I will similarly write that down, possibly
in some common section to which defgeneric and defclass both refer.
Your Friendly Writer
-rpg-
∂06-Feb-88 1034 Common-Lisp-Object-System-mailer Re: Typechecking
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 6 Feb 88 10:34:10 PST
Received: from Semillon.ms by ArpaGateway.ms ; 06 FEB 88 10:34:43 PST
Date: Sat, 6 Feb 88 10:34 PST
From: Gregor.pa@Xerox.COM
Subject: Re: Typechecking
To: Patrick H Dussud <DUSSUD@jenner.csc.ti.com>
cc: common-lisp-object-system@SAIL.STANFORD.EDU
Fcc: BD:>Gregor>mail>outgoing-mail-1.text
In-Reply-To: <2780084688-71255@Jenner>
Message-ID: <880206103419.0.GREGOR@SPIFF.parc.xerox.com>
Line-fold: no
Date: Fri, 5 Feb 88 15:44:48 CST
From: Patrick H Dussud <DUSSUD@jenner.csc.ti.com>
Date: 05 Feb 88 1230 PST
From: Dick Gabriel <RPG@sail.stanford.edu>
Subject: Typechecking
Moon's message caused me to unwedge about what he was talking about. I am
happy to specify the behavior of CLOS when stores violate the :type option
as undefined. Do we have consensus?
I agree this.
Patrick.
This is fine with me as well.
-------
∂06-Feb-88 1146 Common-Lisp-Object-System-mailer DEFGENERIC
To: common-lisp-object-system@SAIL.Stanford.EDU
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>
The material for the behavior Moon specified does not look too bad
when presented this way: defgeneric does an ensure-generic-function,
it removes all methods defined by any previous defgeneric, and then
it adds the methods specified by the :methods. The DEFCLASS description
is similar. The presentation is clear and more concise than the
desciption of the previous behavior.
Anything more to change?
-rpg-
∂06-Feb-88 2218 Common-Lisp-Object-System-mailer Typechecking
Received: from labrea.Stanford.EDU by SAIL.Stanford.EDU with TCP; 6 Feb 88 22:18:31 PST
Received: by labrea.Stanford.EDU; Sat, 6 Feb 88 22:18:50 PST
Received: from bhopal.lucid.com by edsel id AA20504g; Sat, 6 Feb 88 21:47:59 PST
Received: by bhopal id AA12948g; Sat, 6 Feb 88 21:52:32 PST
Date: Sat, 6 Feb 88 21:52:32 PST
From: Jon L White <edsel!jonl@labrea.Stanford.EDU>
Message-Id: <8802070552.AA12948@bhopal.lucid.com>
To: labrea!Moon%STONY-BROOK.SCRC.Symbolics.COM@labrea.Stanford.EDU
Cc: labrea!Common-lisp-object-system%SAIL@labrea.Stanford.EDU
In-Reply-To: David A. Moon's message of Fri, 5 Feb 88 14:40 EST <19880205194056.1.MOON@EUPHRATES.SCRC.Symbolics.COM>
Subject: Typechecking
re: Is there anyone who actually wants "should signal an error" and won't
accept "results are undefined"? If not, let's change it. If so, that
person should be agitating to change Common Lisp as well.
It's on my list of "Clarifications" which need to be written up into
cleanup proposals. The intent DEMANDED by many users is that there
be one mode of compilation/execution that insures memory integrity and
type surety. CLtL's universal excuses "it is an error" and "the results
are undefined", isn't good enough to satisfy that; but Dick's attempt
at phraseology "should signal an error" is close to what's needed.
Certainly CLOS and Common Lisp need to follow the same conventions.
There are numerous other places where the CLOS development has laid
cleanup issues at the Common Lisp door [type-disjointness of some basic
data types, "function specs" for setf generic methods, etc].
-- JonL --
∂07-Feb-88 1228 Common-Lisp-Object-System-mailer Typechecking
To: common-lisp-object-system@SAIL.Stanford.EDU
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>
I agree with Jonl that the right thing to do is to say that
attempting to store a type-improper value in a slot should signal
an error. The desire to be in harmony with CLtL in places like
this where CLtL is clearly wrong is inappropriate. If one wants to
argue that there should be no such thing as a :type option, that
is a different matter.
I suppose this will be one of those situations in which the
behavior of stock-hardware CLOS implementations will be superior
to that of the Lisp machines. The error will be caught at the
point of error and not considerable later.
I agreed to modify the document because I have decided to let nothing
stand in the way of my desire to stop working on the specification.
I don't care how stupid a suggestion is: If it's faster for me to
edit the document than to argue against it, I'll edit.
-rpg-
∂07-Feb-88 1722 Common-Lisp-Object-System-mailer Chapter 2
To: common-lisp-object-system@SAIL.Stanford.EDU
From: Linda DeMichiel <LGD@SAIL.Stanford.EDU>
New functi files are out on Sail. Changes include the addition of call-method,
make-method, related changes to define-method-combination, changes to
defclass (:type), and changes to defgeneric (method descriptions).
-lgd
∂07-Feb-88 1800 Common-Lisp-Object-System-mailer Chapter 1
To: common-lisp-object-system@SAIL.Stanford.EDU
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>
CONCEP.TEX and .DVI are on SAIL. Unless there is some objection,
the versions of chapters 1 and 2 currently on SAIL will be mailed to
X3J13 tomorrow.
-rpg-
∂07-Feb-88 1906 Common-Lisp-Object-System-mailer Typechecking
Received: from labrea.Stanford.EDU by SAIL.Stanford.EDU with TCP; 7 Feb 88 19:06:49 PST
Received: by labrea.Stanford.EDU; Sun, 7 Feb 88 19:07:09 PST
Received: from bhopal.lucid.com by edsel id AA23377g; Sun, 7 Feb 88 18:57:20 PST
Received: by bhopal id AA13999g; Sun, 7 Feb 88 19:01:56 PST
Date: Sun, 7 Feb 88 19:01:56 PST
From: Jon L White <edsel!jonl@labrea.Stanford.EDU>
Message-Id: <8802080301.AA13999@bhopal.lucid.com>
To: labrea!RPG%SAIL@labrea.Stanford.EDU
Cc: labrea!common-lisp-object-system%SAIL@labrea.Stanford.EDU
In-Reply-To: Dick Gabriel's message of 07 Feb 88 1228 PST <8802072131.AA22357@edsel.lucid.com>
Subject: Typechecking
re: I agree with Jonl that the right thing to do is to say that
attempting to store a type-improper value in a slot should signal
an error. . . .
That's just a bit beyond what my opinion on this matter was.
Date: Wed, 27 Jan 88 03:00:04 PST
From: Jon L White <edsel!jonl@labrea.Stanford.EDU>
To: labrea!Bobrow.pa%Xerox.COM@labrea.Stanford.EDU
. . .
My preference as stated before is to
prohibit a rule *requiring* checking of slot values, except that under the
extremal safety settings such checking *may* be required. Note that this
phrasing grants permission for an implementation to do type-checking at all
safety levels, if it so chooses.
I think one reason we have spent so much time going around on this matter
is that Moon started out by attacking the wrong paragraph -- the one from
page 13 in which the phrase something like "because type checking occurs
only under the most strict safety options and in the interpreter". The
sole purpose of that paragraph was to warn the reader that a slot's value
may in fact violate its :type specification; that paragraph by itself did
not carry the burden of saying that slots must be type-checked.
As the story unfolded, he really wanted to attack the part with the phrase
you (erroneously) attribute to me -- "Attempting to store a value in a
slot that does not satisfy the type should signal an error" -- and have it
relaxed from the "should" imperative.
CLtL itself is very weak in specifying the cases where an error "should"
be signalled, particularly in regard to array and structure updates (and
makes virtually no distinction between the various compiler safety levels).
A programmer used to the surety of a strongly-typed language finds this
situation intolerable; consequently, I've put this issue into my file
of things which haven't yet reached the Cleanup committee but ought to.
If ever such an issue should be approved by X3J13, then it most certainly
would apply to CLOS slot stores also.
-- JonL --
∂08-Feb-88 0901 Common-Lisp-Object-System-mailer Re: defgeneric :method option
Received: from RELAY.CS.NET by SAIL.Stanford.EDU with TCP; 8 Feb 88 09:01:36 PST
Received: from relay2.cs.net by RELAY.CS.NET id ac21041; 8 Feb 88 10:23 EST
Received: from csc.ti.com by RELAY.CS.NET id ac22101; 8 Feb 88 10:18 EST
Received: from Jenner by tilde id AA22994; Mon, 8 Feb 88 08:50:57 CST
Message-Id: <2780318877-284364@Jenner>
Date: Mon, 8 Feb 88 08:47:57 CST
From: Patrick H Dussud <DUSSUD@jenner.csc.ti.com>
To: Common-Lisp-Object-System@SAIL.STANFORD.EDU
Subject: Re: defgeneric :method option
In-Reply-To: Msg of Fri, 5 Feb 88 16:34 EST from "David A. Moon" <Moon@scrc-stony-brook.arpa>
A small detail. Since we remove the methods that were defined by
:method in a DEFGENERIC, it would be consistent to allow the change of
the lambda-list if the only methods defined for this generic function
are the one defined by :method. Logically, we are in the case
where there is no method on the updated generic function.
If we agree on this, it means that the remark part of defgeneric must
be updated, and the following form cannot be the expansion of
DEFGENERIC:
(progn
(ensure-generic-function 'name :blah blah blah)
(let ((methods (list (defmethod name blah blah blah)
(defmethod name blah blah blah)
...))
(generic (symbol-function 'name)))
(dolist (method (generic-function-locally-defined-methods generic))
(remove-method generic method))
(setf (generic-function-locally-defined-methods generic) methods)
generic))
Patrick.
∂08-Feb-88 0902 Common-Lisp-Object-System-mailer Re: defgeneric :method option
Received: from RELAY.CS.NET by SAIL.Stanford.EDU with TCP; 8 Feb 88 09:01:48 PST
Received: from relay2.cs.net by RELAY.CS.NET id ad21046; 8 Feb 88 10:24 EST
Received: from csc.ti.com by RELAY.CS.NET id ad22101; 8 Feb 88 10:18 EST
Received: from Jenner by tilde id AA23016; Mon, 8 Feb 88 08:51:37 CST
Message-Id: <2780318934-287847@Jenner>
Date: Mon, 8 Feb 88 08:48:54 CST
From: Patrick H Dussud <DUSSUD@jenner.csc.ti.com>
To: Common-Lisp-Object-System@SAIL.STANFORD.EDU
Subject: Re: defgeneric :method option
In-Reply-To: Msg of Fri, 5 Feb 88 16:34 EST from "David A. Moon" <Moon@scrc-stony-brook.arpa>
A small detail. Since we remove the methods that were defined by
:method in a DEFGENERIC, it would be consistent to allow the change of
the lambda-list if the only methods defined for this generic function
are the one defined by :method. Logically, we are in the case
where there is no method on the updated generic function.
If we agree on this, it means that the remark part of defgeneric must
be updated, and the following form cannot be the expansion of
DEFGENERIC:
(progn
(ensure-generic-function 'name :blah blah blah)
(let ((methods (list (defmethod name blah blah blah)
(defmethod name blah blah blah)
...))
(generic (symbol-function 'name)))
(dolist (method (generic-function-locally-defined-methods generic))
(remove-method generic method))
(setf (generic-function-locally-defined-methods generic) methods)
generic))
Patrick.
∂08-Feb-88 0913 Common-Lisp-Object-System-mailer DEFGENERIC
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 8 Feb 88 09:13:35 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 338573; Sun 7-Feb-88 21:54:32 EST
Date: Mon, 8 Feb 88 12:13 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: DEFGENERIC
To: Dick Gabriel <RPG@SAIL.STANFORD.EDU>
cc: common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: The message of 6 Feb 88 14:46 EST from Dick Gabriel <RPG@SAIL.Stanford.EDU>
Message-ID: <19880208171338.0.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: 06 Feb 88 1146 PST
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>
The material for the behavior Moon specified does not look too bad
when presented this way: defgeneric does an ensure-generic-function,
it removes all methods defined by any previous defgeneric, and then
it adds the methods specified by the :methods. The DEFCLASS description
is similar. The presentation is clear and more concise than the
desciption of the previous behavior.
I prefer to add new methods before removing old ones, to avoid a transient
state in which methods are missing. Remove-method is specified not to error
if the method is already gone. Defining a method is specified (page 1-27) to
create a new method object and discard any existing method object, rather
than modifying the object as defining a class does. Those two facts mean
it's safe to do the add before the remove.
∂08-Feb-88 1017 Common-Lisp-Object-System-mailer CONCEP and FUNCTI
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 8 Feb 88 10:17:44 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 338664; Mon 8-Feb-88 13:17:07 EST
Date: Mon, 8 Feb 88 13:17 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: CONCEP and FUNCTI
To: Dick Gabriel <RPG@SAIL.STANFORD.EDU>, Linda DeMichiel <LGD@SAIL.STANFORD.EDU>
cc: common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: The message of 5 Feb 88 12:48 EST from Dick Gabriel <RPG@SAIL.Stanford.EDU>,
The message of 7 Feb 88 21:00 EST from Dick Gabriel <RPG@SAIL.Stanford.EDU>,
The message of 7 Feb 88 20:22 EST from Linda DeMichiel <LGD@SAIL.Stanford.EDU>
Message-ID: <19880208181719.4.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: 05 Feb 88 0948 PST
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>
There are new CONCEP and FUNCTI .TEX and .DVI files on SAIL. These
incorporate Danny's comments and the infamous (class-name <class>) = junk
change. The impact of this latter change is minimal because many things
deal with proper names, which are still symbols. For example, defclass
and parameter specializers all either define proper names or take
symbols as the names of classes. We hope to send these two chapters
to X3J13 monday.
Date: 07 Feb 88 1800 PST
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>
CONCEP.TEX and .DVI are on SAIL. Unless there is some objection,
the versions of chapters 1 and 2 currently on SAIL will be mailed to
X3J13 tomorrow.
Date: 07 Feb 88 1722 PST
From: Linda DeMichiel <LGD@SAIL.Stanford.EDU>
New functi files are out on Sail. Changes include the addition of call-method,
make-method, related changes to define-method-combination, changes to
defclass (:type), and changes to defgeneric (method descriptions).
I read all of these changes and they are all fine, except note my comment
sent in previous mail today that defgeneric should add new methods
before it removes old one, to avoid transient inconsistent states. This
applies to chapter 2 (chapter 1 is not specific about the order of
operations here).
Thanks for all the hard work you've put into this.
∂08-Feb-88 1021 Common-Lisp-Object-System-mailer Re: defgeneric :method option
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 8 Feb 88 10:21:41 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 338675; Mon 8-Feb-88 13:21:33 EST
Date: Mon, 8 Feb 88 13:21 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: defgeneric :method option
To: Common-Lisp-Object-System@SAIL.STANFORD.EDU
In-Reply-To: <2780318934-287847@Jenner>
Message-ID: <19880208182152.5.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Mon, 8 Feb 88 08:48:54 CST
From: Patrick H Dussud <DUSSUD@jenner.csc.ti.com>
A small detail. Since we remove the methods that were defined by
:method in a DEFGENERIC, it would be consistent to allow the change of
the lambda-list if the only methods defined for this generic function
are the one defined by :method. Logically, we are in the case
where there is no method on the updated generic function.
That's a good point. I agree.
What's in the current version (just looked at a few minutes ago) of
chapters 1 and 2 doesn't really need to be changed for this, since it
doesn't say in specific detail what the macroexpansion of defgeneric
is; I guess that's chapter 3 material. It probably is a good idea to
update the remark part of defgeneric.
If we agree on this, it means that the remark part of defgeneric must
be updated, and the following form cannot be the expansion of
DEFGENERIC:
(progn
(ensure-generic-function 'name :blah blah blah)
(let ((methods (list (defmethod name blah blah blah)
(defmethod name blah blah blah)
...))
(generic (symbol-function 'name)))
(dolist (method (generic-function-locally-defined-methods generic))
(remove-method generic method))
(setf (generic-function-locally-defined-methods generic) methods)
generic))
I agree that your suggestion is right, even though at this moment I don't
know what I think the precise macroexpansion to implement it ought to be.
∂08-Feb-88 1033 Common-Lisp-Object-System-mailer Comments on most recent draft: Chap 1 and 2
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 8 Feb 88 10:33:37 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 338700; Mon 8-Feb-88 13:33:07 EST
Date: Mon, 8 Feb 88 13:33 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Comments on most recent draft: Chap 1 and 2
To: Jon L White <edsel!jonl@labrea.Stanford.EDU>
cc: Common-Lisp-Object-System@SAIL.STANFORD.EDU
In-Reply-To: <8802042246.AA01035@bhopal.lucid.com>
Message-ID: <19880208183318.6.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Thu, 4 Feb 88 14:46:35 PST
From: Jon L White <edsel!jonl@labrea.Stanford.EDU>
....
re: But, haven't we already extended symbol-function to take lists of the
form (setf fn) as an argument. If not, how do we get hold of setf
generic-functions?
I don't recall how the recent discussions on this mailing list suggested
to do it.
This was in a cleanup proposal which the Cleanup committee already approved,
submitted to X3J13 in November, and was approved by X3J13 at that time. I
wasn't there, so I don't know for sure what happened, but I don't think
there was any voting. Perhaps there was some kind of verbal approval.
Anyway my point is that this is as settled an issue as any issue can be
and there's a place where the answer is written down. I don't have a copy
of it myself or I'd send it to you.
∂08-Feb-88 1613 Common-Lisp-Object-System-mailer x3j13 draft
To: common-lisp-object-system@SAIL.Stanford.EDU
From: Linda DeMichiel <LGD@SAIL.Stanford.EDU>
The concep and functi files for the x3j13 draft are now out on Sail. I have
also updated the macros file to print out the document number.
-lgd
∂08-Feb-88 1619 Common-Lisp-Object-System-mailer Re: defgeneric :method option
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 8 Feb 88 16:19:25 PST
Received: from Cabernet.ms by ArpaGateway.ms ; 08 FEB 88 16:00:10 PST
Date: 8 Feb 88 15:59 PST
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Re: defgeneric :method option
In-reply-to: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>'s message of
Mon, 8 Feb 88 13:21 EST
To: Moon@STONY-BROOK.SCRC.Symbolics.COM
cc: Common-Lisp-Object-System@SAIL.STANFORD.EDU
Message-ID: <880208-160010-2750@Xerox>
Another argument for removing methods first is that when a method is added, but
it is shadowed by a method to be removed, the generic function is in as much of
an inconsistent state as when a method is removed and there is no method for a
particlar set of arguments.
It seems to me that doing the remove-method first answers Patrick's issue, and
provides no more inconsistency.
danny
∂08-Feb-88 1636 Common-Lisp-Object-System-mailer Re: defgeneric :method option
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 8 Feb 88 16:36:12 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via INTERNET with SMTP id 339201; 8 Feb 88 19:36:05 EST
Date: Mon, 8 Feb 88 19:36 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: defgeneric :method option
To: Common-Lisp-Object-System@SAIL.STANFORD.EDU
In-Reply-To: <880208-160010-2750@Xerox>
Message-ID: <19880209003616.7.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: 8 Feb 88 15:59 PST
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Another argument for removing methods first is that when a method is added, but
it is shadowed by a method to be removed, the generic function is in as much of
an inconsistent state as when a method is removed and there is no method for a
particlar set of arguments.
It seems to me that doing the remove-method first answers Patrick's issue, and
provides no more inconsistency.
The case I had in mind is the one where the defgeneric has the same :method
options both before and after.
∂10-Feb-88 0019 Common-Lisp-Object-System-mailer Comments on most recent draft: Chap 1 and 2
Received: from labrea.Stanford.EDU by SAIL.Stanford.EDU with TCP; 10 Feb 88 00:19:20 PST
Received: by labrea.Stanford.EDU; Wed, 10 Feb 88 00:19:26 PST
Received: from bhopal.lucid.com by edsel id AA04885g; Wed, 10 Feb 88 00:09:32 PST
Received: by bhopal id AA05040g; Wed, 10 Feb 88 00:14:17 PST
Date: Wed, 10 Feb 88 00:14:17 PST
From: Jon L White <edsel!jonl@labrea.Stanford.EDU>
Message-Id: <8802100814.AA05040@bhopal.lucid.com>
To: labrea!Moon%STONY-BROOK.SCRC.Symbolics.COM@labrea.Stanford.EDU
Cc: labrea!Common-Lisp-Object-System%SAIL@labrea.Stanford.EDU,
sun!franz!smh@labrea.Stanford.EDU,
labrea!rwk%ai.ai.mit.edu@labrea.Stanford.EDU
In-Reply-To: David A. Moon's message of Mon, 8 Feb 88 13:33 EST <19880208183318.6.MOON@EUPHRATES.SCRC.Symbolics.COM>
Subject: Comments on most recent draft: Chap 1 and 2
Date: Thu, 4 Feb 88 14:46:35 PST
From: Jon L White <edsel!jonl@labrea.Stanford.EDU>
....
re: But, haven't we already extended symbol-function to take lists of the
form (setf fn) as an argument. If not, how do we get hold of setf
generic-functions?
I don't recall how the recent discussions on this mailing list suggested
to do it.
This was in a cleanup proposal which the Cleanup committee already approved,
submitted to X3J13 in November, and was approved by X3J13 at that time. I
wasn't there, so I don't know for sure what happened, but I don't think
there was any voting. Perhaps there was some kind of verbal approval.
Anyway my point is that this is as settled an issue as any issue can be
and there's a place where the answer is written down. I don't have a copy
of it myself or I'd send it to you.
You're jumping the gun here. The issue of (setf fn) as a function name
came up as a need from CLOS, but was never presented for approval. Larry
assigned a sub-sub-committee to try to write up some proposal that would
encompass "function specs".
We (this sub-sub-...) have met by conference phone, and discussed what
to do; initially Bob Kerns is working on a "definition specs" proposal
that will clean up and extend the LispMachine's functions specs somewhat.
But we all feel that this is new development -- not just a simple
"clarification", or "cleanup" or minor extension to Common Lisp, and
more serious thought needs to be given to the question. Most likely
there will much discussion about it in Palo Alto next month.
The only thing that's been settled so far is that we all agree on the
need to do something. The actual scope of what is done, the names
of the constructs, and as Danny asks "how do we get hold of setf
generic-functions?" are hardly a settled issues right now. At any rate,
I think he (Danny) was just asking how "we", the CLOS development,
proposed to get access to these things.
-- JonL --
∂10-Feb-88 0858 Common-Lisp-Object-System-mailer Status of SETF functions in Common Lisp
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 10 Feb 88 08:58:45 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 340430; Wed 10-Feb-88 11:57:41 EST
Date: Wed, 10 Feb 88 11:57 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Status of SETF functions in Common Lisp
To: Jon L White <edsel!jonl@labrea.Stanford.EDU>
cc: Common-Lisp-Object-System@SAIL.STANFORD.EDU, sun!franz!smh@labrea.Stanford.EDU,
rwk@AI.AI.MIT.EDU, CL-Cleanup@SAIL.STANFORD.EDU
In-Reply-To: <8802100814.AA05040@bhopal.lucid.com>
Message-ID: <19880210165749.0.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Wed, 10 Feb 88 00:14:17 PST
From: Jon L White <edsel!jonl@labrea.Stanford.EDU>
Date: Thu, 4 Feb 88 14:46:35 PST
From: Jon L White <edsel!jonl@labrea.Stanford.EDU>
....
re: But, haven't we already extended symbol-function to take lists of the
form (setf fn) as an argument. If not, how do we get hold of setf
generic-functions?
I don't recall how the recent discussions on this mailing list suggested
to do it.
This was in a cleanup proposal which the Cleanup committee already approved,
submitted to X3J13 in November, and was approved by X3J13 at that time. I
wasn't there, so I don't know for sure what happened, but I don't think
there was any voting. Perhaps there was some kind of verbal approval.
Anyway my point is that this is as settled an issue as any issue can be
and there's a place where the answer is written down. I don't have a copy
of it myself or I'd send it to you.
You're jumping the gun here. The issue of (setf fn) as a function name
came up as a need from CLOS, but was never presented for approval.
Then I guess one of Larry's status reports saying that issue had been approved
was mistaken, or I misread it.
Larry
assigned a sub-sub-committee to try to write up some proposal that would
encompass "function specs".
That's exactly what I did -not- want to happen. If setf functions,
which CLOS needs, get bogged down in all kinds of extraneous issues
about function specs, which CLOS does not need and does not want,
CLOS could end up getting the shaft. I think standardizing function
specs for Common Lisp is likely to be a fine thing, but I don't want
CLOS to have to wait for it to be completed.
We (this sub-sub-...) have met by conference phone, and discussed what
to do; initially Bob Kerns is working on a "definition specs" proposal
that will clean up and extend the LispMachine's functions specs somewhat.
But we all feel that this is new development -- not just a simple
"clarification", or "cleanup" or minor extension to Common Lisp, and
more serious thought needs to be given to the question. Most likely
there will much discussion about it in Palo Alto next month.
The only thing that's been settled so far is that we all agree on the
need to do something. The actual scope of what is done, the names
of the constructs, and as Danny asks "how do we get hold of setf
generic-functions?" are hardly a settled issues right now. At any rate,
I think he (Danny) was just asking how "we", the CLOS development,
proposed to get access to these things.
I guess I should wait until there is a report of the sub-sub-committee
to read, before drawing any conclusions or making any more intemperate
statements.
∂11-Feb-88 1001 Common-Lisp-Object-System-mailer Re: Status of SETF functions in Common Lisp
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 11 Feb 88 10:01:40 PST
Received: from Salvador.ms by ArpaGateway.ms ; 11 FEB 88 10:00:52 PST
From: masinter.PA@Xerox.COM
Date: 11 Feb 88 10:00:26 PST
Subject: Re: Status of SETF functions in Common Lisp
In-reply-to: Moon@STONY-BROOK.SCRC.Symbolics.COM's message of Wed, 10 Feb 88
11:57 EST, <19880210165749.0.MOON@EUPHRATES.SCRC.Symbolics.COM>
To: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
cc: Jon L White <edsel!jonl@labrea.Stanford.EDU>,
Common-Lisp-Object-System@SAIL.STANFORD.EDU, sun!franz!smh@labrea.Stanford.EDU,
rwk@AI.AI.MIT.EDU, CL-Cleanup@SAIL.STANFORD.EDU
Message-ID: <880211-100052-7099@Xerox>
I've been out with the flu since last Friday afternoon (I thought it was just
jet lag...)
The issue SETF-FUNCTION-VS-SYMBOL was distributed and tentatively approved at
the November 1987 meeting of X3J13.
The larger question of generalizing this beyond SETF functions, and beyond
merely DEFUN and FLET, seemed like it was open for another, larger, more
comprehensive proposal.
I'm still at home today and don't have easy access to all of the files. I'm
hoping I am not too late to get the mailing out for X3J13 of all of the new
issues.
∂11-Feb-88 1437 Common-Lisp-Object-System-mailer Comments on most recent draft: Chap 1 and 2
Received: from labrea.Stanford.EDU by SAIL.Stanford.EDU with TCP; 11 Feb 88 14:37:14 PST
Received: from AI.AI.MIT.EDU by labrea.Stanford.EDU with TCP; Thu, 11 Feb 88 14:35:56 PST
Date: Thu, 11 Feb 88 17:36:46 EST
From: "Robert W. Kerns" <RWK@ai.ai.mit.edu>
Subject: Comments on most recent draft: Chap 1 and 2
To: edsel!jonl@labrea.stanford.edu
Cc: labrea!Common-Lisp-Object-System%SAIL@labrea.stanford.edu,
labrea!Moon%STONY-BROOK.SCRC.Symbolics.COM@labrea.stanford.edu,
labrea!rwk%ai.ai.mit.edu@labrea.stanford.edu,
sun!franz!smh@labrea.stanford.edu
In-Reply-To: Msg of Wed 10 Feb 88 00:14:17 PST from Jon L White <edsel!jonl at labrea.Stanford.EDU>
Message-Id: <325169.880211.RWK@AI.AI.MIT.EDU>
Date: Wed, 10 Feb 88 00:14:17 PST
From: Jon L White <edsel!jonl at labrea.Stanford.EDU>
We (this sub-sub-...) have met by conference phone, and discussed what
to do; initially Bob Kerns is working on a "definition specs" proposal
that will clean up and extend the LispMachine's functions specs somewhat.
But we all feel that this is new development -- not just a simple
"clarification", or "cleanup" or minor extension to Common Lisp, and
more serious thought needs to be given to the question. Most likely
there will much discussion about it in Palo Alto next month.
Actually, it's Steve Haflick who's writing the proposal; I'm writing
the example implementation.
We did decide it would be inappropriate for SYMBOL-FUNCTION to take
a list as its argument, because the name would be confusing.
FUNCTION-DEFINITON is the name I believe we've chosen for the extended
version of SYMBOL-FUNCTION. I expect we will have a detailed proposal
by the March meeting, but we've obviously missed the deadline for voting
on it this time around.
∂12-Feb-88 0018 Common-Lisp-Object-System-mailer Status of SETF functions in Common Lisp
Received: from labrea.Stanford.EDU by SAIL.Stanford.EDU with TCP; 12 Feb 88 00:18:39 PST
Received: by labrea.Stanford.EDU; Fri, 12 Feb 88 00:18:41 PST
Received: from bhopal.lucid.com by edsel id AA15210g; Fri, 12 Feb 88 00:09:42 PST
Received: by bhopal id AA11046g; Fri, 12 Feb 88 00:14:36 PST
Date: Fri, 12 Feb 88 00:14:36 PST
From: Jon L White <edsel!jonl@labrea.Stanford.EDU>
Message-Id: <8802120814.AA11046@bhopal.lucid.com>
To: masinter.PA@xerox.com
Cc: Common-Lisp-Object-System@sail.Stanford.EDU
In-Reply-To: masinter.PA@Xerox.COM's message of 11 Feb 88 10:00:26 PST <880211-100052-7099@Xerox>
Subject: Status of SETF functions in Common Lisp
re: The issue SETF-FUNCTION-VS-SYMBOL was distributed and tentatively approved
at the November 1987 meeting of X3J13.
The issue name was SETF-FUNCTION-VS-MACRO:SETF-FUNCTIONS
It had two parts:
(1) Specify that the expansion of SETF is into a function rather
than merely into a "macro";
(2) Allow a generalized name for this function.
The discussion under this issue is what led to formation of the
"definition specs" group. I doubt that anything that comes up
under the broader scope could conflict with the minimal assumptions
stated in that proposal. In particular, a nomenclature style like
(SETF FN) must be acceptable, and #'(SETF FN) will designate the
function so named.
I certainly remember the overwhelming approval for this direction of
extension, but I think the reason it didn't just end with this single
proposal is that every place that accepts function names is involved,
not just SETF methods.
-- JonL --
∂12-Feb-88 1517 Common-Lisp-Object-System-mailer Issue: SETF-SUB-METHODS
Received: from labrea.Stanford.EDU by SAIL.Stanford.EDU with TCP; 12 Feb 88 15:16:53 PST
Received: by labrea.Stanford.EDU; Fri, 12 Feb 88 15:17:08 PST
Received: from bhopal.lucid.com by edsel id AA18146g; Fri, 12 Feb 88 15:06:49 PST
Received: by bhopal id AA12550g; Fri, 12 Feb 88 15:11:26 PST
Date: Fri, 12 Feb 88 15:11:26 PST
From: Jon L White <edsel!jonl@labrea.Stanford.EDU>
Message-Id: <8802122311.AA12550@bhopal.lucid.com>
To: labrea!Common-Lisp-Object-System%SAIL@labrea.Stanford.EDU
Subject: Issue: SETF-SUB-METHODS
Ken Olum and I [JonL White] have given some thought to the problem that
spurred the issue SETF-METHOD-FOR-SYMBOLS, and feel that the issue as
stated attacks a small manifestation of the problem rather than the root
underlying case. Worse yet, the TEMPORARY-VARIABLE proposal requires a
change which creates a bug in another area of SETF usage [see below].
We propose that the problem lies in understanding of how SETF works when
the SETF expansion for a form like
(<access-fun> <place> ...)
involves the sub-recursive SETF expansion of <place>, or in other words,
when the accessing technique isn't fully specified just by looking at
the get-setf-method of <access-fun>. The class of such <access-fun>'s
is enumerated in CLtL, at the top of p. 96, except that GETF is missing
from that list [we propose that it be added there in the next manual].
This message will propose a clarification the issues of left-to-right
evaluation in such cases, and will also detail the actions that should
be taken by SETF methods on each of these place-types.
!
ISSUE: SETF-SUB-METHODS
References: CLtL pp. 95-96, 99, 105-106, 166
Issue: PUSH-EVALUATION-ORDER
Issue: SETF-METHOD-FOR-SYMBOLS
Category: Clarification
Edit history: Version 1 JonL & KDO 12-Feb-88
Problem description:
Tim Daly of IBM noticed that several implementations do not observe
left-to-right order of evaluation in the following form:
(setq r '(a 1 b 2 c 3))
(setq s r)
(setf (getf r 'b) (progn (setq r nil) 6))
In these implementations, the side-effect of the setq happens before the
evaluation of the "subforms" necessary to fetch the list being updated.
A typical result is that 'r' = (B 6), 's' = (A 1 B 2 C 3) after the
operation. Surely, it should at least be the case that 's' = (A 1 B 6 C 3),
since the expectation is that the B property in this list is being
(destructively) changed.
Similar problems exist with LDB and CHAR-BIT.
It is not necessary to clarify that left-to-right order of evaluation
semantics should be observed; CLtL p99 is quite explicit about that.
Rather, a distinction needs to be made between the computations involved
in "evaluation" of the subforms, and other computations that are implicit
in the notion of "doing an access" or "doing a store".
Proposal: SETF-SUB-METHODS:DELAYED-ACCESS-STORES
Elaborate the documentation of SETF, especially in the case of access
forms whose sub-forms are permitted to be generalized variable references
[and thus which need to call GET-SETF-METHOD during setf macro expansion].
We remember that GET-SETF-METHOD returns the following:
Some temporary variables
A list of value-producing forms
A list of store-variables (normally one).
A storing form.
An accessing form.
Then we want to say that:
Code generated using GET-SETF-METHOD does 2 or 3 of the following
things:
It evaluates the value-producting forms, and binds the temporary
variables to them. This will be called "binding the temporaries."
It evaluates the accessing form to get the old value of the place.
This will be called "doing the access."
It binds the store-variable to a new value and calls the storing form
to install it in the place. This will be called "doing the store."
The forms listed at the top of CLtL p96 permit recursive <place>
specifiers; for each one, we will describe how the sub-recursive
information from GET-SETF-METHOD is used.
LDB:
In a form such as
(SETF (LDB <byte-spec> <place-form>) <value-form>)
the place referred to by the <place-form> must always be both
accessed and updated. Even if the <place-form> refers to a
bignum, the bignum itself will not be modified but rather a new
bignum stored in the <place-form>. Thus this SETF should generate
code to do the following:
1. Evaluate <byte-spec>
2. Bind the temporaries for <place-form>
3. Evaluate <value-form>
4. Do the access to <place-form>
5. Do the store into <place-form> with the given bit-field
replaced with the value from step 3.
If the evaluation of <value-form> in step 3 sets a different
bit-field in the given place then since the access is done later
at step 4 this change will be preserved. See ROTATEF example in
discussion below. Nevertheless the evaluations required for
binding the temporaries are done in step 2, and thus the expected
left-to-right evaluation order is seen.
GETF:
The case of GETF is complicated by the fact that two different
"place" locators are involved: one to use if the specified
indicator is present in the property list, and another if not.
For example, in (SETF (GETF (AREF ... I) 'B) 6), if the I'th slot
of the array is NIL, then that slot must be changed, but if it
contains a list with the property B then only the cons cell with
that property value needs to be changed. This decision cannot be
made at macro-expansion time. It depends entirely on the contents
of the list in question, and so must be delayed until the last
possible moment.
More specifically, the expansion of
(SETF (GETF <place-form> <ind-form>) <value-form>)
should generate code to do the following:
1. Bind the temporaries for <place-form>
2. Do the access to <place-form>
[Binding the temporaries and then doing the access is equivalent to
evaluating the <place-form>.]
3. Evaluate <ind-form> [and save the result in a temporary variable].
4. Check whether the value from 2 has the indicator from 3.
If so:
5A. Find cons-cell after indicator from above
6A. Evaluate <value-form>
7A. RPLACA cons-cell from 5A with value from 6A
[In this case, we do not do a store into <place-form>. When
the indicator is already present then the location specifed
by <place-form> doesn't need a new value.]
If not:
5B. Evaluate <value-form>
6B. Do the access to <place-form>, using the temporaries saved from
step 1 [this is not another evaluation -- but it may involve
some non trivial computation, depending on how complex the
access method really is.].
7B. Do the store into <place-form>, again using the temporaries saved
from step 1, setting it to a list with indicator from 3, new value
from 5B, and old list from 6B.
Rationale:
As a principle,
(setf (foo-a x) (setf (foo-b x) ...))
should always set both of the "slots" of X, even if these slots are
implemented as bit-fields, getf-properties, and so on.
However,
(setf (foo-a x) (setf (foo-a x) ...))
is an error.
Current Practice:
-- Xerox and Franz already operate on GETF according to this perscription.
-- Symbolics and Lucid differ by always doing a setf on the variable
rather than updating the appropriate cons cell of the property list;
additionally, they fail to connect the new value put into 'r' to the
original property list which was 'r's value initially.
-- HP updates the cons cell, but then sets the variable 'r' again, nullifying
the effect of the "(setq r nil)" in the <value-form> computation.
Adoption cost:
Several implementations would require several hours of programmer and
documentation time.
Cost of non-adoption:
Users will think SETF is unnatural in that left-to-right order of
evaluation isn't always observed.
Benefits:
Uniform semantics and portability in the face of recursive "place specifiers"
for SETF. Setf of (LDB ... <place>) and of (GETF <place> ...) will behave
uniformly no matter the nature of the <place>.
Anyone who has copied examples from p.105 and p.106 will continue to
be able to use them.
Conversion Cost:
This is a clarification of a point not sufficiently elaborated in CLtL.
Esthetics:
See "Cost of non-adoption"
Discussion:
In the case that spurred this discussion,
(setq r '(a 1 b 2 c 3))
(setq s r)
(setf (getf r 'b) (progn (setq r nil) 6))
the consequent update is a RPLACA to some list cell -- not a setf of
the variable 'r' -- and thus 'r' should be NIL and 's' should now be
(A 1 B 6 C 3).
There is an interesting parallel between this case for GETF and the
very common mistake made by Lisp programmers with respect to the
function DELETE. How often the complaint is filed that DELETE didn't
do anything when it should have; but in fact the filer simply forgot
that delete can either update some CAR slot of the list originally
given it, or return some tail of the list originally give it, but
not both! E.g.
(setq l '(a a b c d)) ==> (a a b c d)
(delete 'a l) ==> (b c d)
l ==> (a a b c d)
The unwary user thinks that because 'l' is still eq to the original
value that "DELETE didn't do anything". The variability of action
at runtime here parallels the variable choice of location specifier
for (SETF (GETF ...) ...)
A previous proposal to fix this problem was misdirected. It was
phrased as follows:
Proposal: SETF-METHOD-FOR-SYMBOLS:TEMPORARY-VARIABLE
Change the result of (get-setf-method 'foo) from
NIL NIL (#:G1174) (SETQ FOO #:G1174) FOO
to
(#:G1175) (FOO) (#:G1174) (SETQ FOO #:G1174) #:G1175
The problem with this is that it breaks a relatively simple client of
setf technology:
(setq integer #x69)
(rotatef (ldb (byte 4 4) integer) (ldb (byte 4 0) integer))
no longer does the "right thing". Using the prescription for setf
methods on symbols from CLtL p105, the result of this 'rotatef' is
that integer = #x96; using that given by the TEMPORARY-VARIABLE
proposal leads to either #x99 [or #x66 depending on which order
the implementation chooses to do the actual stores in].
In addition if 'integer' is replaced by '(car x)' here then the behavior
is different under the TEMPORARY-VARIABLE proposal because that only
applies to symbols.
Implicitly, two "places" are being specified here to be updated; but
in fact the two places are not independent -- they both involve setq'ing
the variable 'integer'. Furthermore, each store operation implicitly
requires fetching the value from that place in order to combine it
with DPB. It is necessary to delay the accesses until the last moment
before combining with DPB in order to see the side-effects of the
earlier store operations.
∂12-Feb-88 2320 Common-Lisp-Object-System-mailer Issue: SETF-SUB-METHODS
Received: from labrea.Stanford.EDU by SAIL.Stanford.EDU with TCP; 12 Feb 88 23:20:34 PST
Received: by labrea.Stanford.EDU; Fri, 12 Feb 88 23:21:00 PST
Received: from bhopal.lucid.com by edsel id AA19631g; Fri, 12 Feb 88 23:13:20 PST
Received: by bhopal id AA13395g; Fri, 12 Feb 88 23:18:18 PST
Date: Fri, 12 Feb 88 23:18:18 PST
From: Jon L White <edsel!jonl@labrea.Stanford.EDU>
Message-Id: <8802130718.AA13395@bhopal.lucid.com>
To: labrea!Common-Lisp-Object-System%SAIL@labrea.Stanford.EDU
In-Reply-To: Jon L White's message of Fri, 12 Feb 88 15:11:26 PST <8802122311.AA12550@bhopal.lucid.com>
Subject: Issue: SETF-SUB-METHODS
My apologies [nuts! to the mailer] -- this message was intended for the
CL-Cleanup mailing list rather than this one.
-- JonL --
∂15-Feb-88 1548 Common-Lisp-Object-System-mailer 88-002 question
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 15 Feb 88 15:48:07 PST
Received: from Salvador.ms by ArpaGateway.ms ; 15 FEB 88 15:45:21 PST
Date: Mon, 15 Feb 88 15:45:11 PST
From: Pavel.pa@Xerox.COM
Subject: 88-002 question
To: Common-Lisp-Object-System@SAIL.Stanford.Edu
Message-ID: <880215-154521-2198@Xerox>
On page 1-36 of 88-002, in the description of the simple built-in method
combination types, this sentence appears:
``If -operator- is OR, the expression <M_i a_1 . . . a_n> is evaluated
only if <M_j a_1 . . . a_n>, 1 <= j < i, returned NIL.''
Why is OR singled out here for a special description? It is not, for example,
the only cases that doesn't necessarily evaluate all of the applicable methods
(AND may not do so either). It seems like this special case can only serve to
confuse the reader.
Pavel
∂15-Feb-88 1626 Common-Lisp-Object-System-mailer 88-002 Comment
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 15 Feb 88 16:26:49 PST
Received: from Salvador.ms by ArpaGateway.ms ; 15 FEB 88 16:27:25 PST
Date: Mon, 15 Feb 88 16:27:14 PST
From: Pavel.pa@Xerox.COM
Subject: 88-002 Comment
To: Common-Lisp-Object-System@SAIL.Stanford.Edu
Message-ID: <880215-162725-2284@Xerox>
On page 2-72 of 88-002, the following remark appears:
`` The function SLOT-BOUNDP is implemented using SLOT-BOUNDP-USING-CLASS.''
Since SLOT-BOUNDP-USING-CLASS is not described in the document, the usefulness
of this remark is lost on me. The same goes for the similar remarks for the
functions SLOT-MAKUNBOUND and SLOT-VALUE.
Pavel
∂15-Feb-88 1701 Common-Lisp-Object-System-mailer Method Combination
To: common-lisp-object-system@SAIL.Stanford.EDU
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>
The sentence Pavel pointed out should have read:
``For example, if -operator- is OR, the expression <M_i a_1 . . . a_n> is
evaluated only if <M_j a_1 . . . a_n>, 1 <= j < i, returned NIL.''
This is a typical error when you've been staring at a chapter for
over a year.
-rpg-
∂15-Feb-88 1705 Common-Lisp-Object-System-mailer SLOT-BOUNDP
To: common-lisp-object-system@SAIL.Stanford.EDU
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>
I'm glad Pavel is reading the specification CLOSely, because he is
a careful reader. As I mentioned, it is difficult to work on a document
for over a year and not miss things staring you in the face.
A similar remark that Pavel could have made is about the references to
Chapter 3 when there is none supplied. SLOT-BOUNDP-USING-CLASS appeared
in a skeleton chapter 3 that we circulated briefly. I assume that it
will appear in the full blown chapter 3 that Danny and Gregor are
writing. If not, we will either need to document that function or else
eliminate reference to it.
-rpg-
∂08-Mar-88 1510 Common-Lisp-Object-System-mailer new version of mop
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 8 Mar 88 15:10:41 PST
Received: from Semillon.ms by ArpaGateway.ms ; 08 MAR 88 14:28:17 PST
Date: Tue, 8 Mar 88 14:23 PST
From: Gregor.pa@Xerox.COM
Subject: new version of mop
To: common-lisp-object-system@sail.stanford.edu
Fcc: BD:>Gregor>mail>outgoing-mail-1.text
Message-ID: <880308142336.7.GREGOR@SPIFF.parc.xerox.com>
Line-fold: no
There is a new version of the mop on sail. It is called new-mopc.tex.
You will also need to get a new version of the macros file. Danny says
that at one point you have to type a return at TeX to make it happy but
other than that it TeX's fine. We will try to fix that bug soon.
Pages 1-30 of this version are in pretty solid shape. The remaining
pages are OK, but not as solid. We will work on getting those better in
the next day or so.
Patrick, I will mail you the files as soon as I send this message.
-------
∂09-Mar-88 0436 Common-Lisp-Object-System-mailer Re: new version of mop
Received: from uunet.UU.NET by SAIL.Stanford.EDU with TCP; 9 Mar 88 04:35:51 PST
Received: from mcvax.UUCP by uunet.UU.NET (5.54/1.14) with UUCP
id AA05653; Wed, 9 Mar 88 07:36:14 EST
Received: by mcvax.cwi.nl; Wed, 9 Mar 88 13:26:23 +0100 (MET)
Received: by inria.inria.fr; Wed, 9 Mar 88 12:16:32 +0100 (MET)
Date: Wed, 9 Mar 88 12:16:32 +0100
From: mcvax!inria.inria.fr!cointe@uunet.UU.NET (Pierre Cointe)
Message-Id: <8803091116.AA27957@inria.inria.fr>
To: Gregor.pa@xerox.com, common-lisp-object-system@sail.stanford.edu
Subject: Re: new version of mop
Lease could you mail me the files also?
AMities, Pierre
∂09-Mar-88 0903 Common-Lisp-Object-System-mailer Small omission in Chap 2
Received: from burdvax.PRC.Unisys.COM (PRC-GW.PRC.UNISYS.COM) by SAIL.Stanford.EDU with TCP; 9 Mar 88 09:03:36 PST
Received: from bigburd.PRC.Unisys.COM by burdvax.PRC.Unisys.COM (5.54/Domain/jpb/2.9)
id AA06441; Wed, 9 Mar 88 12:03:54 EST
Received: by bigburd.PRC.Unisys.COM (5.54/Domain/jpb/2.9)
id AA28687; Wed, 9 Mar 88 12:03:57 EST
From: fritzson@PRC.Unisys.COM (Richard Fritzson)
Message-Id: <8803091703.AA28687@bigburd.PRC.Unisys.COM>
Received: from Ringmaster by bigburd.PRC.Unisys.COM with PUP; Wed, 9 Mar 88 12:03 EST
To: common-lisp-object-system@sail.stanford.edu
Date: 9 Mar 88 12:01 EST (Wednesday)
To: common-lisp-object-system@sail.stanford.edu
Subject: Small omission in Chap 2
Cc: fritzson@bigburd.PRC.Unisys.COM
The description of the standard-generic-function SLOT-MISSING
indicates that it is called when an attempt is made to access a
non-existent slot of an object, if the object's metaclass is
standard-class. This is a reasonable restriction (although I hate what
happens when I mistakenly apply an accessor function to NIL).
However, the description of the function SLOT-VALUE doesn't include
the restriction to objects whose metaclasses are standard-class. It
seems to say that slot-missing will always be called (even for objects
whose metaclass is built-in-class).
I expect that the former was the intended meaning, but they should
both say the same thing.
-Rich Fritzson
Unisys - Paoli Research Center
P.O. Box 517
Paoli, PA 19301
(215) 648-7606
∂09-Mar-88 1006 Common-Lisp-Object-System-mailer Small omission in Chap 2
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 9 Mar 88 10:06:19 PST
Received: from Semillon.ms by ArpaGateway.ms ; 09 MAR 88 09:45:50 PST
Date: Wed, 9 Mar 88 09:40 PST
From: Gregor.pa@Xerox.COM
Subject: Small omission in Chap 2
To: Richard Fritzson <fritzson@PRC.Unisys.COM>
cc: common-lisp-object-system@sail.stanford.edu
Fcc: BD:>Gregor>mail>outgoing-mail-1.text
In-Reply-To: <8803091703.AA28687@bigburd.PRC.Unisys.COM>
Message-ID: <880309094045.9.GREGOR@SPIFF.parc.xerox.com>
Line-fold: no
Date: 9 Mar 88 12:01 EST (Wednesday)
From: fritzson@PRC.Unisys.COM (Richard Fritzson)
The description of the standard-generic-function SLOT-MISSING
indicates that it is called when an attempt is made to access a
non-existent slot of an object, if the object's metaclass is
standard-class. This is a reasonable restriction (although I hate what
happens when I mistakenly apply an accessor function to NIL).
However, the description of the function SLOT-VALUE doesn't include
the restriction to objects whose metaclasses are standard-class. It
seems to say that slot-missing will always be called (even for objects
whose metaclass is built-in-class).
I expect that the former was the intended meaning, but they should
both say the same thing.
Thanks for catching this and sending us a message.
I believe the reason this bug happened in the document is that we tried
to finesse the issue that slot-value actually called the
generic-function slot-value-using-class. This means that we tried to
put too much of the description of the effect of calling slot-value in
the actual section on slot-value and got tripped up.
I suppose this will be easier to fix now that we actually have chapter
three and can feel free to reference it from chapter 2.
-------
∂09-Mar-88 1843 Common-Lisp-Object-System-mailer CLOS Consortium
Received: from labrea.Stanford.EDU by SAIL.Stanford.EDU with TCP; 9 Mar 88 18:43:13 PST
Received: by labrea.Stanford.EDU; Wed, 9 Mar 88 18:43:58 PST
Received: from bhopal.lucid.com by edsel id AA14794g; Wed, 9 Mar 88 18:28:38 PST
Received: by bhopal id AA09672g; Wed, 9 Mar 88 18:35:03 PST
Date: Wed, 9 Mar 88 18:35:03 PST
From: Linda G. DeMichiel <edsel!lgd@labrea.Stanford.EDU>
Message-Id: <8803100235.AA09672@bhopal.lucid.com>
To: common-lisp-object-system@sail.Stanford.EDU, common-lisp@sail.Stanford.EDU
Subject: CLOS Consortium
Cc: gregor@xerox.com, lgd@sail.Stanford.EDU, rpg@sail.Stanford.EDU
CLOS Consortium
Lucid is currently pursuing the establishment of a consortium to do a
high-performance implementation of the Common Lisp Object System.
The suggested organization for this consortium is the following: Each
member company is to supply either programmers or money, and the
consortium will select a group of individuals to do the implementation
(in the case that more programmers are offered than needed). It is
likely that the current PCL will become the seed for this
implementation. No restrictions will exist as to which companies may
become members of the consortium, and we expect that the implementors
would be from various companies. The result will be a set of sources
either in the public domain or owned by the member companies.
Lucid offers to contribute at least one highly-talented programmer and
the organization for the program.
A mechanism should also be established to handle companies who want to
join the consortium at a later date.
We will be holding an organizational meeting during X3J13 next week
for anyone who may be interested in participating. This meeting is
scheduled for Tuesday, March 15, 8:00p.m., at Hyatt Rickeys,
4219 El Camino Real, Palo Alto.
If you are interested in joining and cannot make the meeting,
please let me know.
Linda DeMichiel
Lucid, Inc.
415-329-8400
∂11-Mar-88 1215 Common-Lisp-Object-System-mailer new version of mopc
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 11 Mar 88 12:15:28 PST
Received: from Semillon.ms by ArpaGateway.ms ; 11 MAR 88 11:32:04 PST
Date: Fri, 11 Mar 88 11:27 PST
From: Gregor.pa@Xerox.COM
Subject: new version of mopc
To: common-lisp-object-system@sail.stanford.edu
Fcc: BD:>Gregor>mail>outgoing-mail-1.text
Message-ID: <880311112713.4.GREGOR@SPIFF.parc.xerox.com>
Line-fold: no
There is a new version of the MOP on sail. This one is called mopc.tex
so there should be no problems with sail filenames.
As a reminder, the directory is [CLS,LSP].
-------
∂18-Mar-88 1746 Common-Lisp-Object-System-mailer Proposed Wording Change to the Error Terminology
To: common-lisp-object-system@SAIL.Stanford.EDU
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>
At the x3j13 meeting this week there was some negative comments
about the definition of ``undefined.'' The following is an attempt
to address those criticisms. The last bullet is the part in question:
****************************************************************************
``When situation $S$ occurs, the results are undefined.''
This terminology has the following meaning:
\beginlist
\item{\bull} If this situation occurs, the results are unpredictable. The
results may range from harmless to fatal to the running system.
\item{\bull} No valid program should cause this situation to happen.
\item{\bull} Implementations are allowed to detect this situation and
signal an error, but no implementation is required to detect the
situation.
\item{\bull} No implementation is allowed to extend the semantics of the
\OS\ to this situation; the effects of the situation may be described
or specified by the implementors, but the effects may not be described
as an extension to the \OS\.
\endlist
****************************************************************************
-rpg-
∂21-Mar-88 0905 Common-Lisp-Object-System-mailer Proposed Wording PicoChange to the Error Terminology
Received: from ALDERAAN.SCRC.Symbolics.COM ([128.81.41.109]) by SAIL.Stanford.EDU with TCP; 21 Mar 88 09:05:15 PST
Received: from CHICOPEE.SCRC.Symbolics.COM by ALDERAAN.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 179921; Mon 21-Mar-88 12:05:42 EST
Date: Mon, 21 Mar 88 12:06 EST
From: Daniel L. Weinreb <DLW@ALDERAAN.SCRC.Symbolics.COM>
Subject: Proposed Wording PicoChange to the Error Terminology
To: RPG@SAIL.Stanford.EDU, common-lisp-object-system@SAIL.Stanford.EDU
In-Reply-To: The message of 18 Mar 88 20:46 EST from Dick Gabriel <RPG@SAIL.Stanford.EDU>
Message-ID: <19880321170608.6.DLW@CHICOPEE.SCRC.Symbolics.COM>
Date: 18 Mar 88 1746 PST
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>
\item{\bull} If this situation occurs, the results are unpredictable. The
results may range from harmless to fatal to the running system.
Pico-nit: the second sentence reads as if the speaker were using the
locution "From X to Y to Z", as in "We carry all brands of cameras, from
Minoltas to Nikons to Canons". (As you might guess, I can't stand this
construct, particularly when the speaker isn't even talking about a
continuous range at all.) I'm not sure how to best fix this, but
"The results may range from harmless to fatal" would be fine with me.
∂21-Mar-88 0810 Common-Lisp-mailer CLOS Status
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 21 Mar 88 08:10:16 PST
Received: from Riesling.ms by ArpaGateway.ms ; 21 MAR 88 08:08:22 PST
Sender: "James_L_Mayer.WBST128"@Xerox.COM
Date: 21 Mar 88 08:07:13 PST (Monday)
Subject: CLOS Status
From: "James_L_Mayer.WBST128"@Xerox.COM
To: Common-Lisp@SAIL.STANFORD.EDU
cc: Common-Lisp-Object-System@SAIL.STANFORD.EDU
Reply-to: "James_L_Mayer.WBST128"@Xerox.COM
Message-ID: <880321-080822-3332@Xerox>
Some questions about the Common Lisp Object System:
(1) What is the status of the standard? When was the last draft spec released
and how can I get a copy?
(2) What is the implementation status? Is PCL still the best approximation
available?
(3) I will be running in Sun Common Lisp. What CLOS options are/will be open to
me?
Thank you.
-- Jim Mayer
∂21-Mar-88 1115 Common-Lisp-Object-System-mailer Proposed Wording PicoChange to the Error Terminology
To: common-lisp-object-system@SAIL.Stanford.EDU
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>
Dan Weinreb's proposed wording change is accepted.
-rpg-
∂21-Mar-88 1245 Common-Lisp-Object-System-mailer Proposed Wording Change to the Error Terminology
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 21 Mar 88 12:45:07 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 367268; Mon 21-Mar-88 15:45:31 EST
Date: Mon, 21 Mar 88 15:45 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Proposed Wording Change to the Error Terminology
To: Dick Gabriel <RPG@SAIL.STANFORD.EDU>
cc: common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: The message of 18 Mar 88 20:46 EST from Dick Gabriel <RPG@SAIL.Stanford.EDU>
Message-ID: <19880321204529.4.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: 18 Mar 88 1746 PST
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>
\item{\bull} No implementation is allowed to extend the semantics of the
\OS\ to this situation; the effects of the situation may be described
or specified by the implementors, but the effects may not be described
as an extension to the \OS\.
I must confess that I cannot figure out what this means. Do you mean simply
that the word "extension" may not appear in the implementation's description?
The previous text "the effects of the situation may be harmless, but they
must remain undefined" seemed a little clearer to me, although still pretty
obscure. With both wordings, I would find it very difficult to decide whether
an implementation did or did not conform to the specification in this respect,
unless the test is simply whether the word "extension" appears in the
documentation (and the documentation is in English).
To try to help clarify this, let me offer two proposed rewordings to choose from:
(1) the effects of the situation may be described or specified by the
implementors, but the description must warn that portable programs cannot
depend on this behavior.
(2) the effects of the situation may be described or specified by the
implementors, but the description must warn that no properly written
program, portable or not, should depend on this behavior.
∂21-Mar-88 1303 Common-Lisp-Object-System-mailer Re: Proposed Wording Change to the Error Terminology
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 21 Mar 88 13:03:24 PST
Received: from Cabernet.ms by ArpaGateway.ms ; 21 MAR 88 12:58:12 PST
Date: Mon, 21 Mar 88 12:58:07 PST
From: Pavel.pa@Xerox.COM
Subject: Re: Proposed Wording Change to the Error Terminology
In-reply-to: <19880321204529.4.MOON@EUPHRATES.SCRC.Symbolics.COM>
To: common-lisp-object-system@SAIL.STANFORD.EDU
Message-ID: <880321-125812-3974@Xerox>
In both of Moon's proposed rewordings, I would much rather see the word
``should'' instead of the word ``must''. It seems ludicrous to me for the
conformance status of an implementation to depend upon its documentation.
Pavel
∂21-Mar-88 1329 Common-Lisp-Object-System-mailer Proposed Wording Change to the Error Terminology (II)
To: common-lisp-object-system@SAIL.Stanford.EDU
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>
When you read this, take out your chapter 1 and read the rest of the
section on error terminology. The suggestions about using the term
``portable'' as part of the definition of ``undefined'' seem to have been
made under the influence of amnesia regarding the rest of the section.
****************************************************************************
``When situation $S$ occurs, the results are undefined.''
This terminology has the following meaning:
\beginlist
\item{\bull} If this situation occurs, the results are unpredictable. The
results may range from harmless to fatal.
\item{\bull} No valid program should cause this situation to happen.
\item{\bull} Implementations are allowed to detect this situation and
signal an error, but no implementation is required to detect the
situation.
\item{\bull} No implementation is allowed to extend the semantics of the
\OS\ to this situation.
\endlist
****************************************************************************
-rpg-
∂21-Mar-88 1436 Common-Lisp-Object-System-mailer Proposed Wording Change to the Error Terminology (II)
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 21 Mar 88 14:35:54 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 367417; Mon 21-Mar-88 17:36:18 EST
Date: Mon, 21 Mar 88 17:36 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Proposed Wording Change to the Error Terminology (II)
To: Dick Gabriel <RPG@SAIL.STANFORD.EDU>
cc: common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: The message of 21 Mar 88 16:29 EST from Dick Gabriel <RPG@SAIL.Stanford.EDU>
Message-ID: <19880321223621.8.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: 21 Mar 88 1329 PST
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>
When you read this, take out your chapter 1 and read the rest of the
section on error terminology. The suggestions about using the term
``portable'' as part of the definition of ``undefined'' seem to have been
made under the influence of amnesia regarding the rest of the section.
Not so. I put that suggestion there specifically to get you to
articulate more clearly the difference between this "undefined"
situation and the "may be extended" situation that follows it in
chapter 1.
\item{\bull} No implementation is allowed to extend the semantics of the
\OS\ to this situation.
This new wording is the vaguest yet, which I assume was your intention.
Maybe that's best, I don't know. It doesn't seem to put to rest the
objections that arose in the X3J13 meeting.
I suppose we could always ask X3J13 to appoint a separate committee for this,
and then use whatever terminology they come up with in the CLOS document.
That way I wouldn't have to feel any responsibility to try to help.
Maybe Sonya will have a good suggestion for how to word this, in two
weeks when she gets back from vacation.
∂21-Mar-88 1628 Common-Lisp-Object-System-mailer Proposed Wording Change to the Error Terminology (II)
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 21 Mar 88 16:28:22 PST
Received: from Semillon.ms by ArpaGateway.ms ; 21 MAR 88 15:57:53 PST
Date: Mon, 21 Mar 88 15:04 PST
From: Gregor.pa@Xerox.COM
Subject: Proposed Wording Change to the Error Terminology (II)
To: Dick Gabriel <RPG@SAIL.Stanford.EDU>
cc: common-lisp-object-system@SAIL.Stanford.EDU
Fcc: BD:>Gregor>mail>outgoing-mail-2.text
In-Reply-To: The message of 21 Mar 88 13:29 PST from Dick Gabriel
<RPG@SAIL.Stanford.EDU>
Message-ID: <880321150455.7.GREGOR@SPIFF.parc.xerox.com>
Line-fold: no
Date: 21 Mar 88 13:29 PST
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>
\item{\bull} No implementation is allowed to extend the semantics of the
\OS\ to this situation.
Well this just solves the problem by being silent on the crucial issue.
Its hard, but I think we can do better. What it we said something like:
No implementation is allowed to extend the semantics of the \OS\ to this
situation. This means that while a given implementation may document
its behavior under the situation, no valid program should count on that
behavior.
During the X3J13 meeting, people were trying to draw a distinction
between documenting what happened in the unspecified situation and
featurizing that situation. I am trying to do something similar here
without resorting to saying anything as gross as `featurize'.
-------
∂22-Mar-88 0018 Common-Lisp-Object-System-mailer Proposed Wording Change to the Error Terminology (II)
Received: from labrea.Stanford.EDU by SAIL.Stanford.EDU with TCP; 22 Mar 88 00:18:02 PST
Received: by labrea.Stanford.EDU; Tue, 22 Mar 88 00:18:40 PST
Received: from bhopal.lucid.com by edsel id AA05815g; Tue, 22 Mar 88 00:14:32 PST
Received: by bhopal id AA02884g; Tue, 22 Mar 88 00:14:13 PST
Date: Tue, 22 Mar 88 00:14:13 PST
From: Jon L White <edsel!jonl@labrea.Stanford.EDU>
Message-Id: <8803220814.AA02884@bhopal.lucid.com>
To: Moon@stony-brook.scrc.symbolics.com
Cc: RPG@sail.stanford.edu, common-lisp-object-system@sail.stanford.edu
In-Reply-To: David A. Moon's message of Mon, 21 Mar 88 17:36 EST <19880321223621.8.MOON@EUPHRATES.SCRC.Symbolics.COM>
Subject: Proposed Wording Change to the Error Terminology (II)
re: [... meaning of "it is undefined" ...]
I suppose we could always ask X3J13 to appoint a separate committee for
this, and then use whatever terminology they come up with in the CLOS
document. That way I wouldn't have to feel any responsibility to try to
help.
It's indeed unfortunate that between the "Error" subcommittee and the
"Cleanup" subcommittee, no one dared tackle the "it is an error" bug.
I sincerely hope, if there is any real action on the matter, that you
will feel the same professional responsibility to offer constructive
comments as you have already done in so many other areas.
-- JonL --
∂22-Mar-88 0811 Common-Lisp-Object-System-mailer Error Terminology
To: common-lisp-object-system@SAIL.Stanford.EDU
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>
Here is the concept behind the terminology. Let D be the domain of
expressions and A a domain of answers. Let E be a function
E: D x Env1 x ... x Envn => A. The meaning is that E takes some
expressions in D plus some number of environments and produces an answer.
E is the meaning of expressions. Let's restrict D to expressions
described in CLOS. We consider projections of the domain of E to D. E is
normally a partial function, being defined for only a subset of D, called
D'. The error terminology has to do with describing the various elements
in D-D'.
There are 4 subsets of D' of interest; call them D'1, D'2, D'3, and D'4.
D'1 is the subset such that attempting to apply E to its elements
results in an error being signaled in all cases and implementations. D'2
is the subset such that attempting to apply E to its elements results in
an error being signaled in the interpreter and under the safest compiler
safety setting in all implementations. D'3 is the subset on which
implementations are free to define new meanings - that is, an
implementation is free to extend the domain of well-definedness to subsets
of D'3. Note that D'1 and D'2 are pairwise disjoint with D'3. Let D'4 be
D'4 = (D-D')-(D'1+D'2+D'3)
We are talking about D'1 when we say ``When situation $S$ occurs, an error
is signaled.''
We are talking about D'2 when we say ``When situation $S$ occurs, an error
should be signaled.''
We are talking about D'3 when we say ``The \CLOS\ may be extended to cover
situation $S$.''
And we are talking about D'4 when we say ``When situation $S$ occurs, the
results are undefined.''
Notice that D'4 has an odd definition: It's not part of the required
well-defined portion of D, we don't want to specify that all
implementations try to detect elements of D'4 even in simple cases, and
the authors of CLOS don't want anyone to extend CLOS to mean anything on
those elements (sometimes because there is no reasonable meaning).
Is D'4 empty? No. Here is an example:
``This implies that a programmer must not use {\bf change-class} inside a
method if any methods for that generic function access any slots, or the
results are undefined.''
We don't want to make implementations detect uses of change-class within a
method that accesses slots that might change as a result of the
change-class. It's ok if an implementation detects it, though. But it's
not ok for any implementor to try to extend CLOS to mean something in this
case. An implementor might specify that when this situation happens the
system has a conniption, but no reasonable programmer would depend on that.
Since we don't seem to want to tell implementors to keep their paws off
of D'4, and since I assume we don't want some mathematical treatment like
this message, how about telling users to keep their hands off of D'4, thus
rendering the attempts of implementors fruitless? Note that we talk about
valid programs, not portable ones. Thus someone living in one implementation
has to think twice about venturing into D'4 land.
**************************************************************************
``When situation $S$ occurs, the results are undefined.''
This terminology has the following meaning:
\beginlist
\item{\bull} If this situation occurs, the results are unpredictable. The
results may range from harmless to fatal.
\item{\bull} Implementations are allowed to detect this situation and
signal an error, but no implementation is required to detect the
situation.
\item{\bull} No valid program may depend on the effects of this
situation, and all valid programs are required to treat the effects
of this situation as unpredictable.
\endlist
****************************************************************************
-rpg-
∂22-Mar-88 1323 Common-Lisp-Object-System-mailer Error Terminology
Received: from labrea.Stanford.EDU by SAIL.Stanford.EDU with TCP; 22 Mar 88 13:23:09 PST
Received: by labrea.Stanford.EDU; Tue, 22 Mar 88 13:23:47 PST
Received: from bhopal.lucid.com by edsel id AA08496g; Tue, 22 Mar 88 13:21:42 PST
Received: by bhopal id AA03932g; Tue, 22 Mar 88 13:21:26 PST
Date: Tue, 22 Mar 88 13:21:26 PST
From: Jon L White <edsel!jonl@labrea.Stanford.EDU>
Message-Id: <8803222121.AA03932@bhopal.lucid.com>
To: RPG@sail.stanford.edu
Cc: common-lisp-object-system@sail.stanford.edu
In-Reply-To: Dick Gabriel's message of 22 Mar 88 0811 PST <8803221617.AA07359@edsel.lucid.com>
Subject: Error Terminology
re: \item{\bull} No valid program may depend on the effects of this
situation, and all valid programs are required to treat the effects
of this situation as unpredictable.
Granting the complaint about "must not extend" being an un-enforceable
clause, then I think this substitute for it is also un-enforceable (i.e.
how can you determine whether a program treats some result as unpredictable).
But the example you have found is brilliant; it cleary shows that the
design cannot be silent about the situations you call D'4. That seems to
be precisely the bug in CLtL -- that silence in this situation implicitly
means "is an error", which for other reasons was defined to cover the
"extensible" case too.
Actually, I didn't think the original wording was all that bad -- "an
implementation must not extend ...". Maybe what was bad about it was
that it wasn't identified as a "designer's note" or "implementation
note".
-- JonL --
∂23-Mar-88 1006 Common-Lisp-Object-System-mailer Some early comments on 88-003
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 23 Mar 88 10:06:00 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 368620; Wed 23-Mar-88 12:03:23 EST
Date: Wed, 23 Mar 88 12:03 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Some early comments on 88-003
To: Common-Lisp-Object-System@SAIL.STANFORD.EDU
Message-ID: <19880323170326.4.MOON@EUPHRATES.SCRC.Symbolics.COM>
I'm holding most of my comments until the next revision of chapter 3
comes out, since Gregor said a lot of things addressed at our meeting
last week will be fixed, and the draft will be coming out within a
couple of weeks. However, here are a couple of points that were not
touched on in that meeting.
Introduction: I'd like to see a one-page description of each protocol,
instead of the present one or two sentence decriptions. This should
cover what the protocol is for, who uses it, who implements it, what
its limitations are, etc. By "who" I mean the CLOS system itself, a
programmer working within that system, or a programmer extending the
system. I'd also like to see a much clearer exposition of contracts
for any generic functions that the user is intended to write methods
for, clarifying constraints on the user's method and constraints on
the caller. Right now the document doesn't even say which generic
functions the user is supposed to be able to write methods for.
I think the naming layer is a little too separate. I don't see why
metaobject classes shouldn't accept the name as an initialization
argument, instead of requiring it to be setf'ed separately. This
name is just documentation: supplying the initialization argument
doesn't cause setf of symbol-class or setf of symbol-function to be
called of course.
I don't understand why accessor methods are said to be created by
an update-dependent method through a special deferred creation
mechanism, rather than being created in the normal fashion as part
of the macro expansion of defclass. Earlier we said that there is
no real difference between an automatically created accessor method
and one that the user writes himself, and that both should run at
the same speed. Page 24 gives a reason (the class may not be fully
defined) for delaying creating accessor methods, but this reason does
not make any sense. There is no such restriction for ordinary methods.
The return value of method-applicable-keywords (by the way, a confusing
name), in the case where any keyword argument is valid because some
method specifies &allow-other-keys, can't work. Page 27 says the symbol
&allow-other-keys is a member of the list to signal this. But that's
ambiguous with the tasteless but valid practice of using the symbol
&allow-other-keys as a keyword argument name. Also representing the
infinite list of all possible acceptable keywords with a finite list is
a poor idea, because anyone who doesn't check for this case and just
does MEMBER is bound to find some symbol that is not a member of the
finite list, even though it is a member of the conceptual infinite list.
This should be changed back to what I proposed originally, which is that
the symbol &allow-other-keys is returned in place of the whole list.
The way reinitialize-instance is specified can't work. The basic
problem is that reinitialize-instance is specified to call
initialize-instance, but an initialize-instance method has no way to
find out whether it was called from reinitialize-instance or from
make-instance. This makes it impossible to implement the specification
(page 30) that "only those arguments explicitly given will affect the
object." First, a user-written initialize-instance :after method that
takes keyword arguments and defaults them is supposed to use the
defaults if called from make-instance, but ignore the defaults if called
from reinitialize-instance; there is no reasonable way to program that.
Second, page 2-59 specifies some permissible optimizations for the
default primary method for initialize-instance, and these optimizations
are incompatible with what reinitialize-instance is doing. The use of
:allow-other-keys in the default primary method for
reinitialize-instance given on page 30 is also a dead giveaway that the
modularity is wrong. In any case, make-instance and
reinitialize-instance aren't the only two functions that need to put an
instance into a consistent "initialized" state. Class-changed and
update-instance-structure have similar needs (as Barmar pointed out
during the plenary meeting). The general outline of the solution to
this is obvious: there should be a generic function that acts as a
common subroutine of all four of those functions, plus any others that
are discovered. Initialization/update code that needs to be shared
should be in methods for this new generic function, code that does not
need to be shared should be in methods for the other generic functions.
The arguments to this new generic function should probably be an
instance, the name of the function that was originally called, and
initargs. Reinitialize-instance should have its own method for dealing
with the slots, instead of reusing the initialize-instance one. I don't
have a full proposal yet, but it would be along these lines. It's also
worth thinking about a more radical idea, in which initialize-instance
would be broken into two parts, to get the modularity right. More work
is needed here but I hope you can see why what's in the document today
won't fly.
Still in the reinitialization section, this update-dependents mechanism
isn't quite right. The problem is the claim that all standard-objects
support update-dependents, which then requires you to say that there are
actually two different mechanisms for recording dependents, the general
one that works for all standard-objects and the efficient one which is
the one that you're really supposed to use. It doesn't make sense to
stick every feature that sounds at all general into standard-object;
that's pre-multiple-inheritance thinking. The update-dependents
mechanism should be provided by a mixin with a documented name, which is
a superclass of every class that needs the feature. I also have some
minor comments about the interface to update-dependents, but they should
wait a bit.
The modularity of update-dependent for classes might be wrong, which
probably means just that I think the keyword arguments it takes aren't
the right ones. I'm not sure of my thinking here yet, but I thought I
ought to mention it now in case it stimulates anyone else to think about
this. When I get time I will do a detailed comparison of this with the
way Flavors does it, which I believe to be both correct and fairly efficient.
Don't forget that the document never says what the "access key instance
access" protocol is for, how it's used, and what the keys are -- Gregor
had to explain that in person. It needs to be in the document.
Issues not covered at all (not a complete list, probably):
- lexical generic functions, relation to class-direct-generic-functions
- compile-time versus run-time environment issues
∂23-Mar-88 1204 Common-Lisp-Object-System-mailer Error Terminology
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 23 Mar 88 12:04:35 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 368822; Wed 23-Mar-88 15:04:32 EST
Date: Wed, 23 Mar 88 15:04 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Error Terminology
To: Dick Gabriel <RPG@SAIL.STANFORD.EDU>
cc: common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: The message of 22 Mar 88 11:11 EST from Dick Gabriel <RPG@SAIL.Stanford.EDU>
Message-ID: <19880323200429.4.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: 22 Mar 88 0811 PST
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>
``When situation $S$ occurs, the results are undefined.''
\item{\bull} No valid program may depend on the effects of this
situation, and all valid programs are required to treat the effects
of this situation as unpredictable.
Agreed.
I'm not concerned about enforceability here, since this is a statement
about programs rather than about implementations, and although it has been
proposed to validate implementations, no one has proposed to validate all
the programs in existence.
Is D'4 empty? No. Here is an example:
``This implies that a programmer must not use {\bf change-class} inside a
method if any methods for that generic function access any slots, or the
results are undefined.''
We don't want to make implementations detect uses of change-class within a
method that accesses slots that might change as a result of the
change-class. It's ok if an implementation detects it, though. But it's
not ok for any implementor to try to extend CLOS to mean something in this
case. An implementor might specify that when this situation happens the
system has a conniption, but no reasonable programmer would depend on that.
Is this really a good example of an element of D'4? I fail to
understand why we want to forbid implementors from making this work.
After all, the only problem with implementing this is that some
optimizations of slot-value, which some people have in mind to use,
can't handle it.
∂23-Mar-88 1314 Common-Lisp-Object-System-mailer D'4 Example
To: common-lisp-object-system@SAIL.Stanford.EDU
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>
Moon writes:
``Is this really a good example of an element of D'4?''
I think it is, but I'm probably thinking of a different situation than
Dave is. If the two classes are similar somehow, such as making the class
of some instance be HONDA-ACCORD when it used to be HONDA-PRELUDE, then it
makes sense to extend CLOS to ``make it work.'' But there is nothing to
prevent someone from changing the class of some instance from
BALLISTIC-TRANSISTOR to MOJO-HAND. In this case what does it mean to be in
a method selected on the basis of the inherent characteristics of an
instance of BALLISTIC-TRANSISTOR when those characteristics all change? If
there are two inheritance chains whose only common superclass is T, it is
not unreasonable to find that the slot names defined by a pair of classes,
one in each chain, could be the same. An implementor could ``make it
work'' that slot accesses to same-named slots could not suffer a
conniption, but what would such accesses mean?
It is reasonable to require that when execution is lexically within some
method, that the author of the method can count on the basic identity of
the instances on the basis of which it was selected to not change. Those
characteristics *might* change, so we do not want to detect such changes,
but for the implementor to mandate some behavior in this bizarre case is
beyond the reasonable scope of his work. Thus even the statement of what
it would mean to extend CLOS to this situation is senseless.
If the class of some instance radically changes (according to the author's
ontology), the meaning of a method that continues while such a change
happens is as stable or sensible as if the names of the slots in that
instance were instantly permutted while the actual offsets used by the
method remained the same. Thus, you could make it work, but you couldn't
make it make sense.
The new wording solves this problem by letting implementors go to
extremes to make it work, while we've told the users to ignore
the work done by the implementors.
-rpg-
∂23-Mar-88 1359 Common-Lisp-Object-System-mailer D'4 Example
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 23 Mar 88 13:59:28 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 368943; Wed 23-Mar-88 16:59:14 EST
Date: Wed, 23 Mar 88 16:59 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: D'4 Example
To: Dick Gabriel <RPG@SAIL.STANFORD.EDU>
cc: common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: The message of 23 Mar 88 16:14 EST from Dick Gabriel <RPG@SAIL.Stanford.EDU>
Message-ID: <19880323215912.0.MOON@EUPHRATES.SCRC.Symbolics.COM>
The text in question didn't say radical changes of class, it said
any change of class.
Maybe what this really shows is that no matter what you define to be
undefined, a sufficiently clever implementor can come up with a subset
of that that clearly should have been specified to be valid for extension
rather than forever undefined. I suppose in a way you said the same
thing by defining the set D'4 as the negation of another set. So what
does this mean? I'm happy with your latest words for describing things
that are specified to be forever undefined, but I'm probably not happy
with some of the things that are specified that way.
∂23-Mar-88 1419 Common-Lisp-Object-System-mailer D'4 Example
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 23 Mar 88 14:19:07 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 368955; Wed 23-Mar-88 17:19:11 EST
Date: Wed, 23 Mar 88 17:18 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: D'4 Example
To: Dick Gabriel <RPG@SAIL.STANFORD.EDU>
cc: common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: The message of 23 Mar 88 16:14 EST from Dick Gabriel <RPG@SAIL.Stanford.EDU>
Supersedes: <19880323215912.0.MOON@EUPHRATES.SCRC.Symbolics.COM>
Comments: Added commentary on all 88-002 usages of the terminology being discussed
Message-ID: <19880323221851.1.MOON@EUPHRATES.SCRC.Symbolics.COM>
The text in question didn't say radical changes of class, it said
any change of class.
Maybe what this really shows is that no matter what you define to be
undefined, a sufficiently clever implementor can come up with a subset
of that that clearly should have been specified to be valid for
extension rather than forever undefined. I suppose in a way you said
the same thing by defining the set D'4 as the negation of another set.
So what does this mean? I'm happy with your latest words for describing
things that are specified to be forever undefined, but I'm probably not
happy with some of the things that are specified that way. Actually,
there are very few of them; ignoring duplicates, only six things are
forever undefined in 88-002 (found by searching for all occurrences
of the word "undefined"):
1. The result of attempting to store in a slot a value that does not
satisfy the type of the slot is undefined.
2. The order of evaluation of default value forms and the order of
evaluation of {\bf :initform} forms are undefined.
3. This implies that a programmer must not use {\bf change-class} inside
a method if any methods for that generic function access any slots, or
the results are undefined.
4. This argument has dynamic extent within {\bf change-class}; if it is
referenced in any way once {\bf class-changed} returns, the results are
undefined.
5. If these [print-object] rules are not obeyed, the results are undefined.
6. The results are undefined if the user attempts to change the class
associated with a symbol that is defined as a type specifier by
{\it Common Lisp: The Language.}
I think 3, 5, and 6 are questionable. I can see reasons why implementation
dependent extensions might make sense for each of these. If you read
the rules referred to, #5 is particularly questionable. Are the results
undefined if a print-object method does not look at *print-escape*?
1, 2, and 4 are noncontroversial, I think.
∂23-Mar-88 1454 Common-Lisp-Object-System-mailer Undefined
To: common-lisp-object-system@SAIL.Stanford.EDU
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>
I have no problems with revisiting all the uses of the term ``undefined''
and changing some or all of them. Moon's instance 2, though, mistakenly
uses the term ``undefined'' when it should say ``unspecified.'' I have
already fixed it (several days ago) in the files:
2. The order of evaluation of default value forms and the order of
evaluation of {\bf :initform} forms are unspecified.
-rpg-
∂24-Mar-88 1855 Common-Lisp-Object-System-mailer Error Terminology
Received: from labrea.Stanford.EDU by SAIL.Stanford.EDU with TCP; 24 Mar 88 18:55:19 PST
Received: by labrea.Stanford.EDU; Thu, 24 Mar 88 17:55:55 PST
Received: from bhopal.lucid.com by edsel id AA19705g; Thu, 24 Mar 88 17:47:27 PST
Received: by bhopal id AA08754g; Thu, 24 Mar 88 17:47:18 PST
Date: Thu, 24 Mar 88 17:47:18 PST
From: Jon L White <edsel!jonl@labrea.Stanford.EDU>
Message-Id: <8803250147.AA08754@bhopal.lucid.com>
To: Moon@stony-brook.scrc.symbolics.com
Cc: RPG@sail.stanford.edu, common-lisp-object-system@sail.stanford.edu
In-Reply-To: David A. Moon's message of Wed, 23 Mar 88 15:04 EST <19880323200429.4.MOON@EUPHRATES.SCRC.Symbolics.COM>
Subject: Error Terminology
re: I'm not concerned about enforceability here, since this is a statement
about programs rather than about implementations,
Well, this is in a proposed part of a "spec"; and if that document makes
its specifications by reference to what "valid programs" do, and if those
specifications are inherently unenforceable, then no user will be able
to determine whether or not his code is a valid program. E.g., it might
be "invalid" only because he presumed that the undefined situation wouldn't
delete all the files in his file system; yet that is not such an unreasonable
requirement to expect even of "undefined" situations.
That's why I think some of this murky area should be handled as "design notes"
or "implemention notes" focusing on intent, rather than as "specifications".
-- JonL --
∂24-Mar-88 2155 Common-Lisp-Object-System-mailer Error Terminology
To: common-lisp-object-system@SAIL.Stanford.EDU
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>
Earlier I mentioned that I had changed the wording surrounding the order
of evaluation of initforms to use the term ``unspecified.'' I suspect that
``unspecified'' needs a definition, so here's an attempt. I think it is
different from ``undefined.''
``When situation $S$ occurs, the results are unspecified.''
This terminology has the following meaning:
\beginlist
\item{\bull} The effects of this situation are not specified in
the \OS, but the effects are harmless.
\item{\bull} Implementations are allowed to specify the effects of
this situation.
\item{\bull} No portable program can depend on the effects of this
situation, and all portable programs are required to treat the situation
as unpredictable but harmless.
\endlist
********************************************************************
On a related note, I think that one of the uses of the term
``undefined'' is suspect, though it is not on Moon's list of
suspect uses:
``\item{\bull} The contents of a slot will always be of type {\tt
(and} $T\sub 1$ $\ldots$ $T\sub n${\tt )} where $T\sub 1 \ldots T\sub n$ are
the values of the {\bf :type} slot options contained in all of the slot
specifiers. If no slot specifier contains the {\bf :type} slot option, the
contents of the slot will always be of type {\bf t}. The result
of attempting to store in a slot
a value that does not satisfy the type of the slot is undefined.''
The suspicion is that this ought to be described some other, less sinister
way:
``\item{\bull} The type of a slot will always be {\tt
(and} $T\sub 1$ $\ldots$ $T\sub n${\tt )} where $T\sub 1 \ldots T\sub n$ are
the values of the {\bf :type} slot options contained in all of the slot
specifiers. If no slot specifier contains the {\bf :type} slot option, the
type of the slot will always be {\bf t}.
No implementation is required to check that the value stored in a slot satisfies
the type of the slot, but implementations are allowed to extend the \OS\
to check such values and to use the type of a slot during compilation.''
-rpg-
∂25-Mar-88 0757 Common-Lisp-Object-System-mailer Ch3
Received: from Sun.COM by SAIL.Stanford.EDU with TCP; 25 Mar 88 07:57:51 PST
Received: from snail.sun.com by Sun.COM (4.0/SMI-4.0)
id AA16688; Fri, 25 Mar 88 07:58:04 PST
Received: from suntana.sun.com by snail.sun.com (4.0/SMI-3.2)
id AA04958; Fri, 25 Mar 88 07:58:16 PST
Received: from localhost by suntana.sun.com (3.2/SMI-3.2)
id AA03308; Fri, 25 Mar 88 07:51:14 PST
Message-Id: <8803251551.AA03308@suntana.sun.com>
To: common-lisp-object-system@sail.stanford.edu
Subject: Ch3
Date: Fri, 25 Mar 88 07:51:12 -0800
From: kempf@Sun.COM
I haven't had time to review it yet, but will in a couple weeks. I basically
agree with Moon's comments posted several days ago.
jak
∂25-Mar-88 1338 Common-Lisp-Object-System-mailer Method-lambda and apply-method-lambda
Received: from ti.com by SAIL.Stanford.EDU with TCP; 25 Mar 88 13:37:52 PST
Received: by ti.com id AA07168; Fri, 25 Mar 88 15:37:05 CST
Received: from Jenner by tilde id AA19733; Fri, 25 Mar 88 14:40:27 CST
Message-Id: <2784314289-5590063@Jenner>
Date: Fri, 25 Mar 88 14:38:09 CST
From: Patrick H Dussud <DUSSUD@Jenner.csc.ti.com>
To: Common-lisp-object-system@sail.stanford.edu
Subject: Method-lambda and apply-method-lambda
I don't think that method-lambda, as describe in 88-003 is good enough. It
captures the contract between a class of generic functions and a class of methods,
so it should be metaclass driven. You can imagine several contracts on a single
implementation.
I propose the following:
Make-method-function is a generic function.
make-method-function GENERIC-FUNCTION QUALIFIERS SPECIALIZERS LAMBDA-FORM &optional MACROEXPAND-ENVIRONMENT
Generic-function is the generic-function object. Note that it can be gotten at
compile-file time and is not expected to change incompatibly between
compile-file time and load time.
QUALIFIERS, SPECIALIZERS, LAMBDA-FORM are the "natural" arguments
MACROEXPAND-ENVIRONMENT is necessary in order to capture the lexical context.
It default to the null macroexpand environment.
The generic function make-method-function returns a function suitable for the
function slot of a method. Its representation is implementation dependent.
The example given in 88-003 would be changed to:
(defun trace-gf (gf)
(let ((nargs (generic-function-required-arguments gf))
(lambda-list (generic-function-lambda-list gf))
(specializers (make-list nargs :initial-element (symbol-class 't)))
(qualifiers '(:around))
(function (compile () (make-method-function gf qualifiers specializers
`(lambda ,lambda-list
(format *trace-output* "~&Hi there.")
(call-next-method))))))
(add-method gf
(make-instance 'standard-method
:lambda-list lambda-list
:specializers specializers
:qualifiers qualifiers
:function function))))
I am not sure that compile should or would work on the result of
make-method-function. This must be decided.
(defmethod (setf foo) :before ((x c1) y &rest z) (do-foo ...))
would expand into
(let ((gf (ensure-generic-function '(setf foo))))
(add-named-method gf '(:before)
'((x c1) y &rest z)
(make-method-function gf '(:before) '(c1 t)
'(lambda (x y &rest z) (do-foo ...))) environment))
---------
apply-method-lambda must be changed for the same reasons.
I propose the following:
apply-method METHOD NEXT-METHOD-LIST &rest ARGUMENTS [ generic function]
apply-method is discriminated on METHOD.
METHOD is the method that needs to be invoked.
NEXT-METHOD-LIST is the list of all the methods that can be invoked by calling
call-next-method.
ARGUMENTS are the "external" arguments to the method. The last one should be a
list of remaining arguments.
Implementations are free to optimize this to internal function calling primitives.
Patrick.
∂25-Mar-88 1351 Common-Lisp-Object-System-mailer Re: Method-lambda and apply-method-lambda
Received: from Sun.COM by SAIL.Stanford.EDU with TCP; 25 Mar 88 13:51:49 PST
Received: from snail.sun.com by Sun.COM (4.0/SMI-4.0)
id AA21629; Fri, 25 Mar 88 13:50:37 PST
Received: from suntana.sun.com by snail.sun.com (4.0/SMI-3.2)
id AA16532; Fri, 25 Mar 88 13:50:48 PST
Received: from localhost by suntana.sun.com (3.2/SMI-3.2)
id AA03557; Fri, 25 Mar 88 13:43:46 PST
Message-Id: <8803252143.AA03557@suntana.sun.com>
To: Patrick H Dussud <DUSSUD@Jenner.csc.ti.com>
Cc: Common-lisp-object-system@sail.stanford.edu
Subject: Re: Method-lambda and apply-method-lambda
In-Reply-To: Your message of Fri, 25 Mar 88 14:38:09 -0600.
<2784314289-5590063@Jenner>
Date: Fri, 25 Mar 88 13:43:43 -0800
From: kempf@Sun.COM
>>I don't think that method-lambda, as describe in 88-003 is good enough. It
>>captures the contract between a class of generic functions and a class of methods,
>>so it should be metaclass driven. You can imagine several contracts on a single
>>implementation.
Why, precisely, do you think there need be any difference between a method
function and any other kind of function? I can understand this for
a generic function, since a generic function has slots, but a method
function has none. It seems to me that most of how a method function
differs is covered by additions to its lexical environment, and that
FUNCALL and APPLY should do.
jak
∂25-Mar-88 1810 Common-Lisp-Object-System-mailer Re: Error Terminology
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 25 Mar 88 18:10:31 PST
Received: from Cabernet.ms by ArpaGateway.ms ; 25 MAR 88 18:06:16 PST
Date: 25 Mar 88 18:06 PST
From: Masinter.pa@Xerox.COM
Subject: Re: Error Terminology
In-reply-to: Dick Gabriel <RPG@SAIL.Stanford.EDU>'s message of 24 Mar 88 21:55
PST
To: RPG@SAIL.Stanford.EDU
cc: common-lisp-object-system@SAIL.Stanford.EDU
Message-ID: <880325-180616-1599@Xerox>
You'll have to define "harmless". I think you'll find it difficult.
∂28-Mar-88 1045 Common-Lisp-Object-System-mailer Re: Method-lambda and apply-method-lambda
Received: from ti.com by SAIL.Stanford.EDU with TCP; 28 Mar 88 10:44:49 PST
Received: by ti.com id AA23660; Mon, 28 Mar 88 12:43:57 CST
Received: from Jenner by tilde id AA07959; Mon, 28 Mar 88 12:41:54 CST
Message-Id: <2784566339-4218491@Jenner>
Date: Mon, 28 Mar 88 12:38:59 CST
From: Patrick H Dussud <DUSSUD@Jenner.csc.ti.com>
To: kempf@sun.com
Cc: Common-lisp-object-system@sail.stanford.edu
Subject: Re: Method-lambda and apply-method-lambda
In-Reply-To: Msg of Fri, 25 Mar 88 13:43:43 -0800 from kempf@sun.com
>>I don't think that method-lambda, as describe in 88-003 is good enough. It
>>captures the contract between a class of generic functions and a class of methods,
>>so it should be metaclass driven. You can imagine several contracts on a single
>>implementation.
Why, precisely, do you think there need be any difference between a method
function and any other kind of function? I can understand this for
a generic function, since a generic function has slots, but a method
function has none. It seems to me that most of how a method function
differs is covered by additions to its lexical environment, and that
FUNCALL and APPLY should do.
I agree that in structure, a method function is like any other function. However
method functions are getting called with(in) an implementation dependent
environment that must be abstracted from the user. This is the motivation for
the encapsulation (method-lambda, apply-method-lambda) given in chapter 3. The
point of my earlier message is that this encapsulation should be metaclass
dependent.
The things that may be contained in the environment are(among others):
Permutation vector(s), call-next-method list.
This environment is distinct from the lexical environment of a closure. That
does not prevent some implementation to code it as if it were a lexical
environment, but that's an implementation choice.
Patrick.
∂28-Mar-88 1142 Common-Lisp-Object-System-mailer Method-lambda and apply-method-lambda
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 28 Mar 88 11:42:48 PST
Received: from Semillon.ms by ArpaGateway.ms ; 28 MAR 88 11:38:48 PST
Date: Mon, 28 Mar 88 11:35 PST
From: Gregor.pa@Xerox.COM
Subject: Method-lambda and apply-method-lambda
To: Patrick H Dussud <DUSSUD@Jenner.csc.ti.com>
cc: Common-lisp-object-system@SAIL.STANFORD.EDU
Fcc: BD:>Gregor>mail>outgoing-mail-2.text
In-Reply-To: <2784314289-5590063@Jenner>
Message-ID: <880328113536.8.GREGOR@SPIFF.parc.xerox.com>
Line-fold: no
Date: Fri, 25 Mar 88 14:38:09 CST
From: Patrick H Dussud <DUSSUD@Jenner.csc.ti.com>
I have two kinds of comments about your proposal. I have some minor
comments about the details of the proposal itself as well as some
serious questions about whether it can work.
I will start with the minor nits.
make-method-function GENERIC-FUNCTION QUALIFIERS SPECIALIZERS
LAMBDA-FORM &optional MACROEXPAND-ENVIRONMENT
Since, as you say, the method function captures the contract between a
class of generic function and a class of method, I think this generic
function should receive the prototype method as an argument as well.
I am not sure that I want to have to pass the method to apply-method?
If I am going to pass the method, why don't I also pass the generic
function?
Also, I am pretty sure we want to make compile work on these, which
brings me to my second point.
How does one write the following code in your proposal:
(defun advise-1-arg-method (method)
(let ((function (method-function method)))
(reinitialize-instance method
:function #'(method-lambda (a)
(format *trace-output* "~&Got arg ~S" a)
(funcall function a)))))
The point is that in this case the `method function lambda' appears
lexically in the source code. That means that it can capture the
lexical variable function. It also means that it is compiled at
compile-file time.
I think both of these are important properties. Perhaps the solution is
to have the generic function you say, but specify in addition that the
standard method returns (METHOD-LAMBDA (..) ...).
-------
∂30-Mar-88 2055 Common-Lisp-Object-System-mailer Error Terminology
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 30 Mar 88 20:54:57 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 373331; Wed 30-Mar-88 23:54:38 EST
Date: Wed, 30 Mar 88 23:54 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Error Terminology
To: Dick Gabriel <RPG@SAIL.STANFORD.EDU>
cc: common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: The message of 25 Mar 88 00:55 EST from Dick Gabriel <RPG@SAIL.Stanford.EDU>
Message-ID: <19880331045444.8.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: 24 Mar 88 2155 PST
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>
....
On a related note, I think that one of the uses of the term
``undefined'' is suspect, though it is not on Moon's list of
suspect uses:
``\item{\bull} The contents of a slot will always be of type {\tt
(and} $T\sub 1$ $\ldots$ $T\sub n${\tt )} where $T\sub 1 \ldots T\sub n$ are
the values of the {\bf :type} slot options contained in all of the slot
specifiers. If no slot specifier contains the {\bf :type} slot option, the
contents of the slot will always be of type {\bf t}. The result
of attempting to store in a slot
a value that does not satisfy the type of the slot is undefined.''
The suspicion is that this ought to be described some other, less sinister
way:
``\item{\bull} The type of a slot will always be {\tt
(and} $T\sub 1$ $\ldots$ $T\sub n${\tt )} where $T\sub 1 \ldots T\sub n$ are
the values of the {\bf :type} slot options contained in all of the slot
specifiers. If no slot specifier contains the {\bf :type} slot option, the
type of the slot will always be {\bf t}.
No implementation is required to check that the value stored in a slot satisfies
the type of the slot, but implementations are allowed to extend the \OS\
to check such values and to use the type of a slot during compilation.''
If I understand what you're saying, the difference is that with the first description,
and implementation is allowed to halt and catch fire if you store a bignum into a slot
that is declared :type fixnum, while with the second description the implementation
is not; it's required either to ignore the type declaration or to signal an error.
Personally, I don't have strong feelings about type declarations, other than that
they should be removed from Common Lisp entirely, so I'm not really in a position
to choose between those two alternatives. However, if the purpose of type declarations
is to allow optimization through specialized implementation techniques, I would
think that you would not want to deny the implementation the freedom that the
first description allows.
Well, that wasn't very clear. What I mean is, the first description allows a
slot to be implemented in a special type-specific way, as one might implement
a local variable. The second description requires slots to be implemented
in the general way that can hold all objects, but allows the type declaration
to be used only for two purposes: to propagate that type through code that reads
the slot, thereby doing type-specific optimization on that code, and to add a
type check to code that writes the slot, signalling an error if the declaration
is violated.
∂31-Mar-88 1355 Common-Lisp-Object-System-mailer Error Terminology
To: common-lisp-object-system@SAIL.Stanford.EDU
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>
RPG writes:
``\item{\bull} The type of a slot will always be {\tt (and}
$T\sub 1$ $\ldots$ $T\sub n${\tt )} where $T\sub 1 \ldots T\sub
n$ are the values of the {\bf :type} slot options contained in
all of the slot specifiers. If no slot specifier contains the
{\bf :type} slot option, the type of the slot will always be
{\bf t}. No implementation is required to check that the value
stored in a slot satisfies the type of the slot, but
implementations are allowed to extend the \OS\ to check such
values and to use the type of a slot during compilation.''
Actually, the part about compilation is intended to imply that an a slot
may be implemented in a type-specific manner, but maybe using the term
``compilation'' might confuse people whose implementations don't have
compilers.
No implementation is required to check that the value
stored in a slot satisfies the type of the slot, but
implementations are allowed to extend the \OS\ to check such
values, to use the type of a slot to determine its representation,
and to use the type of a slot during compilation.
The distinction I was trying to get at with the new formulation is to
separate the type of a slot from the uses of the type of a slot. The
original stated that meaning of the type of a slot was that the contents
of a slot would always be of the type determined by the inherited slot
type. This leads to the embarassing explanation that the contents don't
have to obey this constraint. We wouldn't have to make the embarassing
explanation if we defined what the type of a slot was without referring to
the contents of the slot and left it as an extension that an
implementation could use the type in various ways.
The source of the embarassment is that we say that the meaning of the type
of a slot is that the contents of the slot will always be of that type,
except when it isn't. It struck me as being better to say that the type of
a slot is computed in some manner and that implementations could respect
that type if they wish, which is a less bizarre formulation.
I suppose there is nothing wrong with the original.
-rpg-
∂04-Apr-88 0541 Common-Lisp-Object-System-mailer CLOS, and slot hiding.
Received: from XX.LCS.MIT.EDU by SAIL.Stanford.EDU with TCP; 4 Apr 88 05:41:13 PDT
Received: from LIVE-OAK.LCS.MIT.EDU by XX.LCS.MIT.EDU via Chaosnet; 4 Apr 88 08:41-EDT
Received: from ACORN.Gold-Hill.DialNet.Symbolics.COM by MIT-LIVE-OAK.DialNet.Symbolics.COM via DIAL with SMTP id 86087; 4 Apr 88 08:38:51-EDT
Received: from BOSTON.Gold-Hill.DialNet.Symbolics.COM by ACORN.Gold-Hill.DialNet.Symbolics.COM via CHAOS with CHAOS-MAIL id 97959; Sun 3-Apr-88 13:30:54-EST
Date: Mon, 4 Apr 88 06:48 est
From: mike%acorn@oak.lcs.mit.edu (mike@gold-hill.com after 1-April-88)
COMMENTS: NOTE %acorn@oak... CHANGES TO @GOLD-HILL.COM ON 1-April-88
To: common-lisp-object-system@sail.stanford.edu
Subject: CLOS, and slot hiding.
This query came in from sidney marcowitz in our GOLDWORKS development
group re: CLOS. I think it raises an important issue. Defstruct has
the exact same problem, and I had hoped that CLOS would improve upon
it in this area. The only discussion I find of this is page 1-13 of the
new spec (88-002) which indicates that slots can be shadowed, but
it seems to imply that if not shadowed they cannot be hidden.
...mike beckerle
Gold Hill Computers
----------------------------------------------------------------------
I would like to be able to define a class that has certain advertised
behavior that I can advertise to users who will use it as a superclass
of their own defined classes, as a mixin. All I need to advertise are
the names, calling sequences and effects of some methods. As far as I
can tell, CLOS requires me to also advertise the names of the instance
variables that the methods use internally to contain state, so that
users can avoid name collisions when they define their own instance
variables.
For example, say I define a moving-object class that when included as
a superclass provides methods for things like update-velocity. It
should be transparent whether the internal representation uses
cartesian or radial coordinates. But people who define classes that
inherit from the moving-object class will have to know not to name any
instance variables X and Y, or RAD and THETA, or whatever. Even worse,
I can't change the internal representation of my moving-object class
without the danger of creating collisions with names that my users
have happened to choose. Using macros that create gensyms for the
instance variables, or defining a new package for each such
superclass, or choosing long ugly names that nobody will ever think
of, all seem like unaesthetic solutions. What I really want to be able
to do is define instance variables whose names are local to the
specific superclass.
This is a problem with the specification's support of data
abstraction, modularity, and information hiding. What I would like to
know is if CLOS addresses the problem, and if not, are there specific
reasons that the CLOS committee has for leaving it out of the spec.
Thanks,
-- sidney
∂04-Apr-88 0843 Common-Lisp-Object-System-mailer Re: CLOS, and slot hiding.
Received: from Sun.COM by SAIL.Stanford.EDU with TCP; 4 Apr 88 08:42:56 PDT
Received: from snail.sun.com by Sun.COM (4.0/SMI-4.0)
id AA09986; Mon, 4 Apr 88 08:42:01 PDT
Received: from suntana.sun.com by snail.sun.com (4.0/SMI-3.2)
id AA29447; Mon, 4 Apr 88 08:41:48 PDT
Received: from localhost by suntana.sun.com (3.2/SMI-3.2)
id AA04490; Mon, 4 Apr 88 08:35:01 PDT
Message-Id: <8804041535.AA04490@suntana.sun.com>
To: mike%acorn@oak.lcs.mit.edu (mike@gold-hill.com after 1-April-88)
Cc: common-lisp-object-system@sail.stanford.edu
Subject: Re: CLOS, and slot hiding.
In-Reply-To: Your message of Mon, 04 Apr 88 06:48:00 -0500.
<8804041243.AA08554@Sun.COM>
Date: Mon, 04 Apr 88 08:34:59 -0700
From: kempf@Sun.COM
>I would like to be able to define a class that has certain advertised
>behavior that I can advertise to users who will use it as a superclass
>of their own defined classes, as a mixin. All I need to advertise are
>the names, calling sequences and effects of some methods. As far as I
>can tell, CLOS requires me to also advertise the names of the instance
>variables that the methods use internally to contain state, so that
>users can avoid name collisions when they define their own instance
>variables.
There are a couple of considerations here. Slots with no declared
accessors will not be accessable to the outside world via access
generic functions. One way to achieve encapsulation is to not declare
accessors. This still leaves WITH-SLOTS, but if you don't want the
slots to be accessable through WITH-SLOTS, just don't export their
names from the package in which the class is defined. If you subclass,
it should not matter what you name the slots as long as the names are
in a different package. When resolution of slot names occurs, you will,
of course, get slots with names that are the same except for the package,
but since putting something in a different package is usually an indication
that it is functionally distinct, this should not matter to the structure
of the program. In this manner, you should not have to use gensym's or
other tricks to be sure that no name collisions occur.
>What I really want to be able
>to do is define instance variables whose names are local to the
>specific superclass.
In summary, by not making slots accessable through access functions
and using the package system to isolate the names in the package
where the superclass is defined, you can achieve this.
jak
∂04-Apr-88 0916 Common-Lisp-Object-System-mailer Method-lambda and apply-method-lambda
Received: from ti.com by SAIL.Stanford.EDU with TCP; 4 Apr 88 09:16:10 PDT
Received: by ti.com id AA04225; Mon, 4 Apr 88 11:14:15 CDT
Message-Id: <8804041614.AA04225@ti.com>
Received: by tilde id AA18273; Mon, 4 Apr 88 11:03:35 CDT
Date: Mon, 4 Apr 88 11:03:35 CDT
From: dussud@ausome.csc.ti.com
To: common-lisp-object-system@sail.stanford.edu
Subject: Method-lambda and apply-method-lambda
From: Patrick H Dussud <DUSSUD@Jenner>
To: Gregor.pa@XEROX.COM
Cc: Common-lisp-object-system@SAIL.STANFORD.EDU
Subject: Re: Method-lambda and apply-method-lambda
In-Reply-To: Msg of Mon, 28 Mar 88 11:35 PST from Gregor.pa@XEROX.COM
Date: Mon, 28 Mar 88 11:35 PST
From: Gregor.pa@XEROX.COM
Subject: Method-lambda and apply-method-lambda
Date: Fri, 25 Mar 88 14:38:09 CST
From: Patrick H Dussud <DUSSUD@Jenner.csc.ti.com>
I have two kinds of comments about your proposal. I have some minor
comments about the details of the proposal itself as well as some
serious questions about whether it can work.
I will start with the minor nits.
make-method-function GENERIC-FUNCTION QUALIFIERS SPECIALIZERS
LAMBDA-FORM &optional MACROEXPAND-ENVIRONMENT
Since, as you say, the method function captures the contract between a
class of generic function and a class of method, I think this generic
function should receive the prototype method as an argument as well.
I am not sure that I want to have to pass the method to apply-method?
If I am going to pass the method, why don't I also pass the generic
function?
Good idea. I didn't put a method in there because I was under the impression
that the modularity of the contract is broken. The way compute-effective-method
is designed, the contract between the generic function and the method, abstracted
by the local macro call-method will not depend on the method. Maybe I didn't
look hard enough.
Also, I am pretty sure we want to make compile work on these, which
brings me to my second point.
How does one write the following code in your proposal:
(defun advise-1-arg-method (method)
(let ((function (method-function method)))
(reinitialize-instance method
:function #'(method-lambda (a)
(format *trace-output* "~&Got arg ~S" a)
(funcall function a)))))
You can do:
(defun advise-1-arg-method (method)
(let ((function (method-function method)))
(reinitialize-instance method
:function
(make-method-function
(method-generic-function method)
(method-qualifiers method)
(method-parameter-specializers method)
`(lambda (a)
(format *trace-output* "~&Got arg ~S" a)
(funcall ,function a)))lambda-form )))
The point is that in this case the `method function lambda' appears
lexically in the source code. That means that it can capture the
lexical variable function. It also means that it is compiled at
compile-file time.
I see your point, but the problem is that you can't decide at compile time what
will be the implementation of the abstraction without knowing anything about the
class of generic function, or the method.
The problem with make-method-function being a function instead of a macro is
that even if all of[ GENERIC-FUNCTION QUALIFIERS SPECIALIZERS ] were known at
compile time and constant, we couldn't do the closure you had in mind.
If this is seen as a problem, we could make make-method-function be a macro
that evaluates GENERIC-FUNCTION QUALIFIERS SPECIALIZERS at macroexpand time then
calls the generic function:
Expand-method-function GENERIC-FUNCTION QUALIFIERS SPECIALIZERS
LAMBDA-FORM &optional MACROEXPAND-ENVIRONMENT
which produces something like:
(function (lambda ....)). Note that what it produces is implementation dependent
and can substitute lambda for something else.
Note that your example does not work anyway. You call the original method
function, but the continuation (a representation of the next-methods list) is
lost in the process. I am sure that we need something, like a local macro
defined inside of the expanded method function, that allows someone to get at
the continuation, and then pass it to apply-method-function. I'll have to think
more about it.
Patrick.
∂04-Apr-88 1522 Common-Lisp-Object-System-mailer add-named-xxx
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 4 Apr 88 15:22:01 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 04 APR 88 14:42:31 PDT
Date: Mon, 4 Apr 88 11:20 PDT
From: Gregor.pa@Xerox.COM
Subject: add-named-xxx
To: common-lisp-object-system@SAIL.STANFORD.EDU
Fcc: BD:>Gregor>mail>outgoing-mail-2.text
Message-ID: <880404112029.5.GREGOR@SPIFF.parc.xerox.com>
Line-fold: no
At our last meeting, there was some sentiment for making the behavior of
add-named-class, ensure-generic-function and add-named-method more
uniform. This message attempts to address those issues.
I have spent some time thinking about this, and I still feel that while
add-named-class and ensure-generic-function are similar, add-named-method
is different.
One way to see this is to think about the defining forms which these
functions are the analog of. add-named-class is the analog of defclass;
ensure-generic-function is the analog of defgeneric; add-named-method is
the analog of defmethod.
defclass and defgeneric each provide a way to specify the class of the
metaobject created. One could imagine wanting to specialize the code
that created and installed that metaobject based on its class. As an
example, one could imagine wanting to have special code for creating a
installing instances of a particular metaclass, say my-standard-class.
One way to provide this kind of functionality is to have add-named-class
and ensure-generic-functions each be generic-functions which specialize
on their first argument. The first argument is the prototype instance
of the class of metaobject being created. This leads us to define these
generic functions as:
(defmethod add-named-class ((proto standard-class)
&key name
superclass-names
slot-specifications
options
environment)
;; This method implements the behavior specified for defclass
;; with (:metaclass standard-class).
)
(defmethod ensure-generic-function ((proto standard-generic-function)
&key name
lambda-list
argument-precedence-order
.
(rest of options from pg 2-49)
.
)
;; This method implements the behavior specified for defgeneric
;; with (:generic-function-class standard-class).
)
On the other hand, defmethod provides no mechanism for controlling the
class of the generic function or the method it creates. For this reason
it doesn't make sense for add-named-method to have that ability.
On the other hand, it is possible to make add-named-method a little more
uniform by having it take keyword arguments which get passed on to the
make-instance of the method.
(defun add-named-method (generic-function-name &rest keys
&key qualifiers
specializers
&allow-other-keys)
(let* ((gf (ensure-generic-function
(class-prototype (class-named 'standard-generic-function))
:name generic-function-name))
(new-method (apply #'make-instance
(generic-function-method-class gf)
keys))
(old-method (get-method gf qualifiers specializers)))
(when old-method (remove-method gf old-method))
(add-method gf new-method)))
An alternate proposal would be to give the caller of add-named-method
more control over the arguments passed to ensure-generic-function. My
feeling is that it isn't worth cluttering up add-named-method to do
that. If someone wants more control over the arguments to
ensure-generic-function they can call it directly.
------
∂04-Apr-88 1631 Common-Lisp-Object-System-mailer Some early comments on 88-003 (accessor methods)
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 4 Apr 88 16:31:46 PDT
Received: from Semillon.ms by ArpaGateway.ms ; 04 APR 88 15:42:15 PDT
Date: Mon, 4 Apr 88 15:41 PDT
From: Gregor.pa@Xerox.COM
Subject: Some early comments on 88-003 (accessor methods)
To: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>, Bobrow.PA@Xerox.COM
cc: Common-Lisp-Object-System@SAIL.STANFORD.EDU
Fcc: BD:>Gregor>mail>outgoing-mail-2.text
In-Reply-To: <19880323170326.4.MOON@EUPHRATES.SCRC.Symbolics.COM>
Message-ID: <880404154147.8.GREGOR@SPIFF.parc.xerox.com>
Line-fold: no
Date: Wed, 23 Mar 88 12:03 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
I don't understand why accessor methods are said to be created by
an update-dependent method through a special deferred creation
mechanism, rather than being created in the normal fashion as part
of the macro expansion of defclass. Earlier we said that there is
no real difference between an automatically created accessor method
and one that the user writes himself, and that both should run at
the same speed. Page 24 gives a reason (the class may not be fully
defined) for delaying creating accessor methods, but this reason does
not make any sense. There is no such restriction for ordinary
methods.
Right, accessor methods want to be added and removed by
initialize-instance and reinitialize-instance respectively. The
specific bit of illogic which is responsible for this is the third
complete paragraph of page 24 which says:
"These are generated by the update-dependent method on standard-class.
It cannot be generated by initialize-instance since the class may not
be fully defined when initialize-instance is called."
As you point out, a class does not need to be fully defined to define
methods on it.
-------
∂04-Apr-88 1632 Common-Lisp-Object-System-mailer update-instance-structure
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 4 Apr 88 16:31:53 PDT
Received: from Semillon.ms by ArpaGateway.ms ; 04 APR 88 16:20:26 PDT
Date: Mon, 4 Apr 88 16:20 PDT
From: Gregor.pa@Xerox.COM
Subject: update-instance-structure
To: common-lisp-object-system@SAIL.STANFORD.EDU
Fcc: BD:>Gregor>mail>outgoing-mail-2.text
Message-ID: <880404162009.9.GREGOR@SPIFF.parc.xerox.com>
Line-fold: no
There are a couple of minor problems with the update-instance-structure
section in chapter 2.
In the arguments section, the first sentence where it says "When
make-instances-obsolete is invoked..". It probably means something more
like "After make-instances-obsolete is invoked, of after a class has
been redefined, all the instances must be updated. When an instance is
being updated ...".
In the examples section. I believe the defmethod of
update-instance-structure should be at the end of the example. Even
though this code might work interpreted (in some implementations) it
definitely won't compile. This is because setf of position-rho is used
before position-rho is defined.
-------
∂05-Apr-88 1746 Common-Lisp-Object-System-mailer (re)initialization revisited
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 5 Apr 88 17:46:28 PDT
Received: from Semillon.ms by ArpaGateway.ms ; 05 APR 88 17:37:58 PDT
Date: Tue, 5 Apr 88 17:37 PDT
From: Gregor.PA@Xerox.COM, Bobrow.PA@Xerox.COM
Sender: Gregor.pa@GRAPEVINE.parc.xerox.com
Subject: (re)initialization revisited
To: common-lisp-object-system@SAIL.STANFORD.EDU
Fcc: BD:>Gregor>mail>outgoing-mail-2.text
Message-ID: <880405173737.1.GREGOR@SPIFF.parc.xerox.com>
Line-fold: no
This message addresses some important issues which we would like to get
feedback on as soon as possible. Please send at least some sort of
comment as soon as time permits.
This message attempts to address some of the problems Moon brought up
with reinitialize-instance. In thinking about this we came to the some
of the same conclusions he did, namely that we really needed to
integrate initialize-instance, update-instance-structure and
class-changed a little more. Having done that, we were able to fit
reinitialize-instance in quite easily.
This message is in 3 parts. The first part introduces the observations
we made when we went back to think about this. The second part outlines
change to existing parts of chapter 1 and 2. The third part starts from
that change, modularizes it better and introduces reinitialize-instance.
Part 1.
First lets look at the existing generic functions initialize-instance,
update-instance-structure and class-changed. In looking at the
specification of these functions, we can see that the each one's primary
method is doing something very close to identical. They could almost be
calling a common subroutine. The most interesting thing is that except
for some very special cases, they could in fact call a common
subroutine.
We believe, that while we were designing these sections, we (all of us)
must have intended for them to "call" that common subroutine.
Part 2.
So, we would like to modify the primary methods for initialize-instance,
update-instance-structure and class-changed to have a common behavior.
This common behavior could be defined by a shared subroutine.
(defun subroutine (instance &rest initargs)
.. initialize the slots from the initargs in the order ..
.. specified in chapter 1 ..
..
.. for any slots which are still unbound, initialize ..
.. them from their initforms ..
)
In order to understand this change fully, lets look carefully at cases
where this would actually cause different behavior:
INITIALIZE-INSTANCE
This is actually not a change for initialize instance. There may be
some problems with some of the mentioned optimizations, but lets come
back to that in another message.
UPDATE-INSTANCE-STRUCTURE
(Note that update-instance-structure would not call the subroutine
with any initargs, so only the part which sets unbound slots to the
result of evaluating their initforms would apply.)
The difference is when a slot appears in both the old and new versions
of the class, has an initform in the new version of the class, and is
unbound in an instance at the time of class redefinition.
Under the old definition, update-instance-structure would do nothing
to the slot. Under the new definition, update-instance-structure
would set the slot to the result of evaluating its initform.
CLASS-CHANGED
Class-changed is exactly analogous to update-instance-structure. If
there is a slot which appears in both the old and new classes, and
that slot is unbound at the time of change-class, the new definition
of class-changed will set its value to the result of evaluating the
initform. The old definition wouldn't have touched the slot at all.
Part 3.
The proposal we would like to make is to have the subroutine which does
the setting of slots described above moved to the standard method of a
new generic function called shared-initialize (all names here could be
improved upon). Initialize-instance, update-instance-structure and
class-changed would each call shared-initialize.
Users who wanted to add code to one of the specific update functions
would define a method on it. Users who want to add initialization code
common to all the ways an instance is initialize would define a method
on shared-initialize. In order for user defined methods on
shared-initialize to know why they were being called, shared-initialize
takes an argument which is the name of the generic function which called
it.
Given this structure, reinitialize-instance would be a generic-function
just like the other three, its standard method would call
shared-initialize with 'reinitialize-instance as the second argument.
Here is some sample code:
(defmethod make-instance ((class standard-class) &rest initargs)
(let ((defaulted-initargs (default-initargs class initargs)))
(check-initargs class defaulted-initargs)
(let ((instance (apply #'allocate-instance class defaulted-initargs)))
(apply #'initialize-instance class defaulted-initargs)
instance)))
(defmethod initialize-instance ((instance standard-object) &rest initargs)
(apply #'shared-initialize instance
'initialize-instance
initargs))
(defmethod reinitialize-instance ((instance standard-object) &rest initargs)
(apply #'shared-initialize instance
'reinitialize-instance
initargs))
(defmethod update-instance-structure ((instance standard-object)
added-slots
discarded-slots
property-list)
(shared-initialize instance 'update-instance-structure))
(defmethod class-changed ((previous standard-object)
(current standard-object))
(shared-initialize current 'class-changed))
(defmethod shared-initialize ((instance standard-object)
caller
&rest initargs)
.. initialize the slots from the initargs in the order ..
.. specified in chapter 1 ..
..
.. for any slots which are still unbound, initialize ..
.. them from their initforms ..
)
-------
∂05-Apr-88 1957 Common-Lisp-Object-System-mailer comments from Kathy Chapman
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 5 Apr 88 19:54:21 PDT
Received: from Semillon.ms by ArpaGateway.ms ; 05 APR 88 19:52:00 PDT
Date: Tue, 5 Apr 88 19:51 PDT
From: Gregor.pa@Xerox.COM
Subject: comments from Kathy Chapman
To: common-lisp-object-system@SAIL.STANFORD.EDU
Fcc: BD:>Gregor>mail>outgoing-mail-2.text
Message-ID: <880405195147.4.GREGOR@SPIFF.parc.xerox.com>
Line-fold: no
In this morning's mail, I received handwritten comments from Kathy
Chapman on Chapters 1 and 2. She seems to have marked up almost all
the pages, so typing her comments in isn't practical.
Mostly she seems to have homed in on places in the specification where
the language was confusing to her. Given that, I think the best thing
to do is for me to give this marked up copy to Dick and Linda so that
they can address her comments by going through the draft. If they find
comments that require we look into some of our past design decisions
then we can do that on the mailing list in the usual way.
(Editors note, I wanted to say "that require us to reassess some of
our design decisions", but it seems that `reassess' is not a real word.)
If someone else really wants a copy of her comments I could make one and
send it to you, but I don't plan to make any copies unless someone asks
me to.
P.S. Has anyone else received comments from people?
-------
∂06-Apr-88 0905 Common-Lisp-Object-System-mailer Re: CLOS, and slot hiding.
Received: from XX.LCS.MIT.EDU by SAIL.Stanford.EDU with TCP; 6 Apr 88 09:04:57 PDT
Received: from LIVE-OAK.LCS.MIT.EDU by XX.LCS.MIT.EDU via Chaosnet; 5 Apr 88 15:28-EDT
Received: from ACORN.Gold-Hill.DialNet.Symbolics.COM (DIAL|DIAL|6210575) by MIT-LIVE-OAK.DialNet.Symbolics.COM via DIAL with SMTP id 86206; 5 Apr 88 15:25:28-EDT
Received: from BOSTON.Gold-Hill.DialNet.Symbolics.COM by ACORN.Gold-Hill.DialNet.Symbolics.COM via CHAOS with CHAOS-MAIL id 98107; Tue 5-Apr-88 15:06:08-EST
Date: Tue, 5 Apr 88 15:05 est
From: mike%acorn@oak.lcs.mit.edu (mike@gold-hill.com any day now)
COMMENTS: NOTE %acorn@oak... WILL BECOME @GOLD-HILL.COM ANY DAY NOW
To: kempf@Sun.COM
Subject: Re: CLOS, and slot hiding.
Cc: mike%acorn@oak.lcs.mit.edu,
common-lisp-object-system@sail.stanford.edu,
sidney,
ariel@oz.ai.mit.edu
Date: Mon, 04 Apr 88 08:34:59 -0700
From: kempf@Sun.COM
>I would like to be able to define a class that has certain advertised
>behavior that I can advertise to users who will use it as a superclass
>of their own defined classes, as a mixin. All I need to advertise are
>the names, calling sequences and effects of some methods. As far as I
>can tell, CLOS requires me to also advertise the names of the instance
>variables that the methods use internally to contain state, so that
>users can avoid name collisions when they define their own instance
>variables.
There are a couple of considerations here. Slots with no declared
accessors will not be accessable to the outside world via access
generic functions. One way to achieve encapsulation is to not declare
accessors. This still leaves WITH-SLOTS, but if you don't want the
slots to be accessable through WITH-SLOTS, just don't export their
names from the package in which the class is defined.
If the package system is really the only way to do this, then there
is really a deep flaw in CLOS. It doesn't support classes for
data-abstraction very well at all. Was this issue every discussed
in the design of CLOS?
I would like to submit this as an official comment on the draft CLOS
spec (88-002) for x3j13. The class abstraction should support this
kind of information hiding. The names of the instance variables
should not be automatically inherited by the subclasses in every
case. One must at least be able to override this default behavior and
specify that certain instance variables are specific to the class and
thereby avoid the name conflict problem with instance variables of
subclasses.
If you subclass,
it should not matter what you name the slots as long as the names are
in a different package. When resolution of slot names occurs, you will,
of course, get slots with names that are the same except for the package,
but since putting something in a different package is usually an indication
that it is functionally distinct, this should not matter to the structure
of the program. In this manner, you should not have to use gensym's or
other tricks to be sure that no name collisions occur.
I want to use the SAME name, i.e. identical package, etc.
Using a separate package is unacceptable, as the package namespace in
common lisp is a GLOBAL space. Gensymming symbols and gensymming packages
seem like the same solution to me, both equally "tricky".
>What I really want to be able
>to do is define instance variables whose names are local to the
>specific superclass.
...mike beckerle
Gold Hill
P.S.,
I really should give credit to marty hiller (ariel@oz) for
this observation about CLOS instance variables. She passed it
on to sidney who passed it on to me.
∂06-Apr-88 0938 Common-Lisp-Object-System-mailer Re: CLOS, and slot hiding.
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 6 Apr 88 09:38:07 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 376793; Wed 6-Apr-88 12:37:45 EDT
Date: Wed, 6 Apr 88 12:37 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: CLOS, and slot hiding.
To: "mike@gold-hill.com any day now" <mike%acorn@oak.lcs.mit.edu>
cc: common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: The message of 5 Apr 88 16:05 EDT from "mike@gold-hill.com any day now" <mike%acorn@oak.lcs.mit.edu>
Message-ID: <19880406163752.2.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Tue, 5 Apr 88 15:05 est
From: mike%acorn@oak.lcs.mit.edu (mike@gold-hill.com any day now)
>I would like to be able to define a class that has certain advertised
>behavior that I can advertise to users who will use it as a superclass
>of their own defined classes, as a mixin. All I need to advertise are
>the names, calling sequences and effects of some methods. As far as I
>can tell, CLOS requires me to also advertise the names of the instance
>variables that the methods use internally to contain state, so that
>users can avoid name collisions when they define their own instance
>variables.
If the package system is really the only way to do this, then there
is really a deep flaw in CLOS. It doesn't support classes for
data-abstraction very well at all. Was this issue every discussed
in the design of CLOS?
Yes, it was discussed quite a bit. Providing more information-hiding than
the package system provides was decided to be not a goal of CLOS, basically
because it's difficult. Since the goals of CLOS have never been published,
this is my personal judgement, but I think the other members of the CLOS
working group would agree that this is a reasonably accurate statement of
the history.
Note that I am not claiming that CLOS provides excellent data abstraction
and I am not claiming that it would be useless to have explicit modularity
boundaries between subclasses and superclasses. What I am claiming, and
there is plenty of support for this claim, is that standardization efforts
that do too much innovation beyond current practice generally fail. CLOS
is a standardization effort, not primarily a research effort, and there is
no expectation that researchers won't develop a better language a few years
from now. The purpose of CLOS is to satisfy the people who need a
standard, portable, efficient, well-documented object-oriented programming
language right now and can't afford to wait a few years. I in fact think
that CLOS as it is went too far in the research direction and that is why
it's taken longer than expected and come out a little more incoherent than
we would like.
I would like to submit this as an official comment on the draft CLOS
spec (88-002) for x3j13.
Fine. I'm not sure if we've yet appointed anyone to be responsible for
collecting the official comments and making sure we have responses to them,
but this exchange of messages should be saved as part of that.
The class abstraction should support this
kind of information hiding. The names of the instance variables
should not be automatically inherited by the subclasses in every
case. One must at least be able to override this default behavior and
specify that certain instance variables are specific to the class and
thereby avoid the name conflict problem with instance variables of
subclasses.
I imagine that chapter 3 will provide the ability to extend the system in
this direction, if you define your own methods to replace enough of the
standard programmer interface. Since chapter 3 is barely started at this
point, it's hard to make a definitive statement about that.
∂06-Apr-88 0939 Common-Lisp-Object-System-mailer Re: CLOS, and slot hiding.
Received: from Sun.COM by SAIL.Stanford.EDU with TCP; 6 Apr 88 09:39:47 PDT
Received: from snail.sun.com by Sun.COM (4.0/SMI-4.0)
id AA16269; Wed, 6 Apr 88 09:38:03 PDT
Received: from suntana.sun.com by snail.sun.com (4.0/SMI-3.2)
id AA28297; Wed, 6 Apr 88 09:37:38 PDT
Received: from localhost by suntana.sun.com (3.2/SMI-3.2)
id AA01292; Wed, 6 Apr 88 09:30:52 PDT
Message-Id: <8804061630.AA01292@suntana.sun.com>
To: mike%acorn@oak.lcs.mit.edu (mike@gold-hill.com any day now)
Cc: kempf@Sun.COM, common-lisp-object-system@sail.stanford.edu,
sidney@XX.LCS.MIT.EDU, ariel@oz.ai.mit.edu
Subject: Re: CLOS, and slot hiding.
In-Reply-To: Your message of Tue, 05 Apr 88 15:05:00 -0500.
<8804061603.AA15672@Sun.COM>
Date: Wed, 06 Apr 88 09:30:08 -0700
From: kempf@Sun.COM
>I would like to be able to define a class that has certain advertised
>behavior that I can advertise to users who will use it as a superclass
>of their own defined classes, as a mixin. All I need to advertise are
>the names, calling sequences and effects of some methods. As far as I
>can tell, CLOS requires me to also advertise the names of the instance
>variables that the methods use internally to contain state, so that
>users can avoid name collisions when they define their own instance
>variables.
There are a couple of considerations here. Slots with no declared
accessors will not be accessable to the outside world via access
generic functions. One way to achieve encapsulation is to not declare
accessors. This still leaves WITH-SLOTS, but if you don't want the
slots to be accessable through WITH-SLOTS, just don't export their
names from the package in which the class is defined.
>If the package system is really the only way to do this, then there
>is really a deep flaw in CLOS. It doesn't support classes for
>data-abstraction very well at all. Was this issue every discussed
>in the design of CLOS?
I think you have this backwards. The flaw (if any) is not in CLOS but
in Common Lisp. The charter of the CLOS committee was to design an
object-oriented extension to Common Lisp, not to "fix" Common Lisp.
Common Lisp deals with modularity using name spaces, packages being
one method of establishing a name space. If the extension were to
Scheme, then environments would be used for establishing the modularity
needed for data abstraction. Extending any language for object-oriented
programming requires that the fundamental abstraction principles of
the language be used and compatibility extended, otherwise the extension
becomes unworkable.
If you subclass,
it should not matter what you name the slots as long as the names are
in a different package. When resolution of slot names occurs, you will,
of course, get slots with names that are the same except for the package,
but since putting something in a different package is usually an indication
that it is functionally distinct, this should not matter to the structure
of the program. In this manner, you should not have to use gensym's or
other tricks to be sure that no name collisions occur.
>I want to use the SAME name, i.e. identical package, etc.
>Using a separate package is unacceptable, as the package namespace in
>common lisp is a GLOBAL space. Gensymming symbols and gensymming packages
>seem like the same solution to me, both equally "tricky".
You want to use the same name but have it mean something different? I'm
confused, sorry. Do you have an example?
jak
∂06-Apr-88 1015 Common-Lisp-Object-System-mailer Re: CLOS, and slot hiding.
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 6 Apr 88 10:15:08 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 376857; Wed 6-Apr-88 13:14:28 EDT
Date: Wed, 6 Apr 88 13:14 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: CLOS, and slot hiding.
To: kempf@Sun.COM
cc: "mike@gold-hill.com any day now" <mike%acorn@oak.lcs.mit.edu>, common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: <8804061630.AA01292@suntana.sun.com>
Message-ID: <19880406171441.7.MOON@EUPHRATES.SCRC.Symbolics.COM>
Jim, I agree with your very clear message and wish I had said the same
things in mine, in addition to what I did say.
∂06-Apr-88 1043 Common-Lisp-Object-System-mailer Reinitialization
To: common-lisp-object-system@SAIL.Stanford.EDU
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>
I agree with Gregor's analysis and with the general outline
of his solution. However, I usually have bad reactions to
the use of flags to signify flow of control, so I would prefer
to have some other means of implementing the solution.
Here is a possibility, which has its own drawbacks, but which I
believe is better. Sample code:
(defmethod make-instance ((class standard-class) &rest initargs)
(let ((defaulted-initargs (default-initargs class initargs)))
(check-initargs class defaulted-initargs)
(let ((instance (apply #'allocate-instance class defaulted-initargs)))
(apply #'initialize-instance class #'shared-initialize
defaulted-initargs)
instance)))
(defmethod initialize-instance ((instance standard-object)
initializer &rest initargs)
(apply initializer instance initargs))
(defmethod reinitialize-instance ((instance standard-object)
initializer &rest initargs)
(apply initializer instance initargs))
(defmethod update-instance-structure ((instance standard-object)
initializer
added-slots
discarded-slots
property-list)
(funcall initializer instance))
(defmethod class-changed ((previous standard-object)
(current standard-object)
initializer)
(funcall initializer current))
(defmethod shared-initialize ((instance standard-object)
&rest initargs)
.. initialize the slots from the initargs in the order ..
.. specified in chapter 1 ..
..
.. for any slots which are still unbound, initialize ..
.. them from their initforms ..
)
Each of the update functions would take an extra argument, which
is the initializer function. The code that invokes the updaters would
pass in the current function binding for shared-initialize. If a user
wanted to alter the shared initialization behavior he would define
a method on shared-initialize, as in Gregor's scheme.
If he wanted to define radical new update behavior, he would define
methods on initialize-instance, reinitialize-instance,
update-instance-structure, or class-changed, as in Gregor's scheme.
Suppose he wanted to change the initialization behavior for, let's
say, reinitialize-instance. In Gregor's scheme he would write a method
on shared-initialize which discriminated on the identity of the second
argument. In my proposal he would write a method on
reinitialize-instance and supply a new initializer function:
(defmethod reinitialize-instance ((instance my-class)
initializer &rest initargs)
(generic-labels
((shared-initialize ...))
(apply #'call-next-method instance shared-initialize initargs)))
[Note that due to the 2 namespace problem I cannot use with-added-methods
to easily alter initializer. Maybe we should change with-added-methods
to add an option that says here is the generic function to use?
(defmethod reinitialize-instance ((instance my-class)
initializer &rest initargs)
(with-added-methods
(initializer (instance &rest initargs)
(:generic-function initializer)
(:method ((instance my-class) &rest initargs) ...))
(apply #'call-next-method instance initializer initargs)))]
-rpg-
∂06-Apr-88 1047 Common-Lisp-Object-System-mailer Re: CLOS, and slot hiding.
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 6 Apr 88 10:47:06 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 06 APR 88 10:41:01 PDT
Date: 6 Apr 88 10:40 PDT
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Re: CLOS, and slot hiding.
In-reply-to: mike%acorn@LIVE-OAK.LCS.MIT.EDU (mike@gold-hill.com any day now)'s
message of Tue, 5 Apr 88 15:05 est
To: mike%acorn@LIVE-OAK.LCS.MIT.EDU
cc: kempf@Sun.COM, common-lisp-object-system@sail.stanford.edu,
sidney@LIVE-OAK.LCS.MIT.EDU, ariel@oz.ai.mit.edu
Message-ID: <880406-104101-5261@Xerox>
I agree with the comments made by Moon about the design goals of CLOS. Alan
Snyder made a big pitch for having encapsulation be an important goal for the
Common Lisp community, and it was rejected. One reason is that it was hard (as
Moon mentioned) and another is because it does not fit into the philosophy of
Lisp, which has always prided itself on being an open system (this is the point
that Jim made so well).
The metaobject protocol (Chapter 3) is designed to allow people to experiment
with additions and variations on the language. Jim Kempf put Common Objects on
top of CLOS using the MOP, and Common Objects has some of the properties you are
talking about (if I understand you properly). Do you have a real example in
mind?
danny
∂06-Apr-88 1253 Common-Lisp-Object-System-mailer Reinitialization
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 6 Apr 88 12:53:07 PDT
Received: from Semillon.ms by ArpaGateway.ms ; 06 APR 88 12:52:38 PDT
Date: Wed, 6 Apr 88 12:52 PDT
From: Gregor.pa@Xerox.COM
Subject: Reinitialization
To: Dick Gabriel <RPG@SAIL.STANFORD.EDU>
cc: common-lisp-object-system@SAIL.STANFORD.EDU
Fcc: BD:>Gregor>mail>outgoing-mail-2.text
In-Reply-To: The message of 6 Apr 88 10:43 PDT from Dick Gabriel
<RPG@SAIL.Stanford.EDU>
Message-ID: <880406125216.9.GREGOR@SPIFF.parc.xerox.com>
Line-fold: no
Date: 06 Apr 88 10:43 PDT
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>
I agree with Gregor's analysis and with the general outline
of his solution. However, I usually have bad reactions to
the use of flags to signify flow of control, so I would prefer
to have some other means of implementing the solution.
I think the solution you propose doesn't address one of the problems we
were trying to address. Looking back over our message, it seems we
didn't make that goal clear at all. This message tries to show why we
decided to use a flag to communicate the caller of shared-initialize.
Moon may also want to comment on this since his message originally
suggested the use of this kind of flag.
The basic idea is that while it might be nice in practise so separate
out the code into the part which is specific to each of the three
pseudo-initialization functions and the part which is common, this kind
of separation may be difficult to do in practise. For this reason it is
convenient to have the shared code know who its caller was. That way
the shared code can make decisions about what to do based on who its
caller is.
As you point out this can be done by passing in a function which will be
called, but this just reduces it to having to separate any code which is
partly shared and partly initializer-specific. The intuition is that
this would prove to be a pain in practise.
Each of the update functions would take an extra argument, which
is the initializer function. The code that invokes the updaters would
pass in the current function binding for shared-initialize. If a user
wanted to alter the shared initialization behavior he would define
a method on shared-initialize, as in Gregor's scheme.
If he wanted to define radical new update behavior, he would define
methods on initialize-instance, reinitialize-instance,
update-instance-structure, or class-changed, as in Gregor's scheme.
As I mentioned, the problem isn't when you want to define radically new
behavior its when you want to define behavior which is a complex blend,
Suppose he wanted to change the initialization behavior for, let's
say, reinitialize-instance. In Gregor's scheme he would write a method
on shared-initialize which discriminated on the identity of the second
argument. In my proposal he would write a method on
reinitialize-instance and supply a new initializer function:
I never intended for anyone to write methods which discriminated on the
identity of the caller argument. I would certainly think it was a bad
idea to do that. My idea was that the caller argument would be used as
a flag inside the method itself.
-------
∂06-Apr-88 1940 Common-Lisp-Object-System-mailer Reinitialization
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 6 Apr 88 19:40:38 PDT
Received: from Semillon.ms by ArpaGateway.ms ; 06 APR 88 19:40:27 PDT
Date: Wed, 6 Apr 88 19:40 PDT
From: Gregor.pa@Xerox.COM
Subject: Reinitialization
To: Dick Gabriel <RPG@SAIL.STANFORD.EDU>
cc: common-lisp-object-system@SAIL.STANFORD.EDU
Fcc: BD:>Gregor>mail>outgoing-mail-2.text
In-Reply-To: <880406125216.9.GREGOR@SPIFF.parc.xerox.com>
Message-ID: <880406194011.3.GREGOR@SPIFF.parc.xerox.com>
Line-fold: no
After further consideration, I am pretty happy with Dicks amended
version of the proposal Danny and I mailed out.
What do other people think?
-------
∂07-Apr-88 1011 Common-Lisp-Object-System-mailer Re: Reinitialization
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 7 Apr 88 10:11:22 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 07 APR 88 10:08:05 PDT
Date: 7 Apr 88 10:07 PDT
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Re: Reinitialization
In-reply-to: Dick Gabriel <RPG@SAIL.Stanford.EDU>'s message of 06 Apr 88 10:43
PDT
To: RPG@SAIL.Stanford.EDU
cc: common-lisp-object-system@SAIL.Stanford.EDU
Message-ID: <880407-100805-6877@Xerox>
I liked Dick's variation on our proposal; that is, I like using a function
rather than a flag for variation. I also support his proposed addition to
with-added-methods of an option to specify the generic function.
However, there is a bug in the proposal. Since users never call class-changed
or update-instance-structure (only the system does), there is no way to change
the call, and shared-initialize will always be used (so why have an argument).
Here are two proposals to fix the bug, neither of which I like a lot, though I
prefer the first.
1) Have a generic function compute-initialization-function which returns
a function to use:
(defmethod compute-initialization-function ((instance standard-object))
#'shared-initialize)
(defmethod initialize-instance ((instance standard-object)
&rest initargs)
(apply (compute-initialization-function instance) instance initargs))
(defmethod update-instance-structure ((instance standard-object)
added-slots
discarded-slots
property-list)
(funcall (compute-initialization-function instance) instance))
etc.
2) Have a special variable *initializer* with the a default value
#'shared-initialize, and use that. For some additonal flexibility, one could
allow initialize-instance and reinitialize-instance to have keyword argument
:initializer whose default value is *initializer*.
(defmethod update-instance-structure ((instance standard-object)
added-slots
discarded-slots
property-list)
(funcall *initializer* instance))
(defmethod initialize-instance ((instance standard-object)
&key (initializer *initializer*)
&rest initargs)
(apply initializer instance initargs))
∂07-Apr-88 1040 Common-Lisp-Object-System-mailer Re: Reinitialization
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 7 Apr 88 10:40:32 PDT
Received: from Semillon.ms by ArpaGateway.ms ; 07 APR 88 10:35:20 PDT
Date: Thu, 7 Apr 88 10:34 PDT
From: Gregor.pa@Xerox.COM
Subject: Re: Reinitialization
To: Danny Bobrow <Bobrow.pa@Xerox.COM>
cc: RPG@SAIL.STANFORD.EDU, common-lisp-object-system@SAIL.STANFORD.EDU
Fcc: BD:>Gregor>mail>outgoing-mail-2.text
In-Reply-To: <880407-100805-6877@Xerox>
Message-ID: <880407103428.1.GREGOR@SPIFF.parc.xerox.com>
Line-fold: no
Date: 7 Apr 88 10:07 PDT
From: Danny Bobrow <Bobrow.pa>
I liked Dick's variation on our proposal; that is, I like using a function
rather than a flag for variation. I also support his proposed addition to
with-added-methods of an option to specify the generic function.
However, there is a bug in the proposal. Since users never call class-changed
or update-instance-structure (only the system does), there is no way to change
the call, and shared-initialize will always be used (so why have an argument).
Here are two proposals to fix the bug, neither of which I like a lot, though I
prefer the first.
Unfortunately, I don't think either of these can work. The first
reduces directly to a stripped down version of the original proposal,
the second doesn't work for other reasons.
1) Have a generic function compute-initialization-function which returns
a function to use:
(defmethod compute-initialization-function ((instance standard-object))
#'shared-initialize)
(defmethod initialize-instance ((instance standard-object)
&rest initargs)
(apply (compute-initialization-function instance) instance initargs))
.
.
The problem here is that because compute-intialization-function doesn't
accept an argument saying who the caller is, it will return the same
value when called by initialize-instance, update-instance-structure etc.
This in effect reduces this to the original proposal where
initialize-instance, class-changed etc. all call the same generic
function. The only difference is that the function isn't called with an
argument that says who its caller is.
2) Have a special variable *initializer* with the a default value
#'shared-initialize, and use that. For some additonal flexibility, one could
allow initialize-instance and reinitialize-instance to have keyword argument
:initializer whose default value is *initializer*.
The problem with this is that the user can never know when
update-instance-structure is going to be called. This means it is
impossible to control the binding of *intializer* around calls to
update-instance-structure.
Given this I see two alternatives:
Modify proposal 1 above so that there are three generic functions,
initialize-instance-initializer, update-instance-structure-initializer,
and class-changed-intiailizer. The standard method on each of these
would return #'shared-initialize. Users could define their own methods
on these generic function to control what shared initializer got used.
This is essentially Dick's proposal debugged.
Go back to the proposal Danny and I had originally.
-------
∂07-Apr-88 1221 Common-Lisp-Object-System-mailer Re: (re)initialization revisited
Received: from Sun.COM by SAIL.Stanford.EDU with TCP; 7 Apr 88 12:21:43 PDT
Received: from snail.sun.com by Sun.COM (4.0/SMI-4.0)
id AA07958; Thu, 7 Apr 88 12:20:53 PDT
Received: from suntana.sun.com by snail.sun.com (4.0/SMI-3.2)
id AA27708; Thu, 7 Apr 88 12:20:32 PDT
Received: from localhost by suntana.sun.com (3.2/SMI-3.2)
id AA01613; Thu, 7 Apr 88 12:13:48 PDT
Message-Id: <8804071913.AA01613@suntana.sun.com>
To: common-lisp-object-system@SAIL.STANFORD.EDU
Subject: Re: (re)initialization revisited
In-Reply-To: Your message of Tue, 05 Apr 88 17:37:00 -0700.
<880405173737.1.GREGOR@SPIFF.parc.xerox.com>
Date: Thu, 07 Apr 88 12:13:45 -0700
From: kempf@Sun.COM
I agree in principle with Gregor's initial message, but all the proposed
alternatives so far leave me less than enthusiastic. The proposed
solutions have involved using flags, function valued arguments, or
special variables to pass a function to four different generic
functions which ultimately end up doing the same thing. I'm going to argue
for a solution which I proposed briefly last fall, namely collapsing
the initialization functions into one or two.
In particular, note the following:
1) Neither update-instance-structure nor class-changed is meant to be
called by the programmer. This means that their interfaces could be
rearranged to be the same, by either bundling the added-slots,
discarded-slots and property list arguments to update-instance-structure
and simply passing the old object, or by unbundling
the previous object instance to class-changed and passing that information
in the form update-instance-structure currently gets it. The kernel code which
calls the merged function would take care of formatting the call correctly.
This would allow one of the two functions to be dropped.
2) This leaves initialize-instance and reinitialize-instance. Since
these interfaces are the same anyway, what's the point of having two
differently named functions? Chapter 3 implies that the only difference
is that reinitialize-instance takes care of calling update-dependents,
but this seems to have been dropped in the current discussion. Even
if it hadn't been, update-dependents could be called upon initialization
also, with, of course, no result since no dependents have been registered
on object's state yet.
This leaves us with two functions:
1) A reinitialization function, which gets passed an assortment of information
on the old object in some form and the new object, allowing the user
to customize what precisely the initialization arguments are.
2) A raw initialization function, which gets passed the initargs.
Since 1) basically needs to call 2), I'd suggest that 1) be named
reinitialize-instance, and that 2) be named initialize-instance.
There are plenty of refinements one could think of, like how to
allow the kind of pairwise generic dispatch which
class-changed currently allows, and details to fill in, but
rather than take the time to hack out some code, I'd like to
see what people think of this idea.
The problem with the other solutions proposed so far is that they
end up adding yet another function to CLOS, when some judicious
subtraction and rearrangement might reduce the bulk somewhat and
also provide a more unified solution.
jak
∂07-Apr-88 1451 Common-Lisp-Object-System-mailer Reinitialization
To: common-lisp-object-system@SAIL.Stanford.EDU
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>
Something seems horrendously complicated about this whole affair.
There are 4 updaters:
initialize-instance
reinitialize-instance
update-instance-structure
class-changed
In this message I use reinitialize-instance as the example.
These are called from parts unknown. They invoke a shared initializer
called shared-initialize. We want to be able write methods to change the
shared behavior, the gross behavior of the 4 updaters, and the behavior of
some of the behavior of what is otherwise shared initialization bahavior.
The modification in the last case depends only on which of the updaters
invokes the shared initialization rountine.
The point of my proposal was to have the shared initialization GF passed
in as an argument to the updaters so that one could write code that only
knew the calling protocol for the updater and which could locally modify
the initializer routine passed in. This way, even though shared-initialize
is always passed in, you can hack with it directly by writing a simple
method on reinitialize-instance.
Suppose reinitialize-instance were like this:
(defmethod reinitialize-instance ((instance standard-object)
initializer &rest initargs)
<An incredibly hairy mess>
...
(apply initializer instance initargs)
...
<Weirder stuff than a human can imagine>)
Now if we want to alter the behavior of shared-initialize when
called by reinitialize-instance on some more specific class than
standard-object, we do the following:
(defmethod reinitialize-instance ((instance some-class)
initializer &rest initargs)
(with-generic-function-messed-with
(initializer (mess-with-generic-function initializer))
(apply #'call-next-method instance initializer initargs)))
Notice we don't have to worry about the hairy mess and weird stuff in the
body of reinitialize-instance, *and* we've used an object-oriented programming
style to boot! This seems like the most common case to me.
Suppose you want to change shared-initialize to take an argument saying
why it was called. In this case I guess you can modify shared-initialize
to accept an special initargs pair encoding the caller and then modify the
4 updaters as above but to add the initargs pair.
Suppose we want to alter the behavior of shared-initialize any time
reinitialize-instance is called and there is no more specific class to
specialize reinitialize-instance on. Here it's trickier, but doable:
(let ((r-i #'reinitialize-instance))
(with-generic-function-messed-with
(initializer (mess-with-generic-function #'shared-initialize))
(defmethod reinitialize-instance ((instance some-class)
initializer &rest initargs)
(apply r-i instance initializer initargs))
(defun fix-this-mess ()
(setf (symbol-function 'reinitialize-instance) r-i))))
How would you do this with the flag scenario? I thought you would do this:
(let ((s-i #'shared-initialize))
(defmethod shared-initialize ((instance standard-object)
caller
&rest initargs)
(if (member caller <my-silly-behvior-group>)
<flail-like-a-quail>
(apply s-i instance caller initargs)))
...))
Looks pretty familiar, eh?
Is there a better way? I think there is a simpler way:
(defmethod reinitialize-instance ((instance standard-object)
&rest initargs)
(reinitializeds-shared-initialize instance initargs))
(defmethod reinitializeds-shared-initialize ((instance standard-object)
&rest initargs)
(apply #'shared-initialize instance initargs))
(defmethod shared-initialize ((instance standard-object)
&rest initargs)
...)
Now to alter the gross behavior, reinitialize-instance gets changed. To
alter the shared behavior, shared-initialize gets changed. To alter some
of the shared behavior, leaving the rest alone,
reinitializeds-shared-initialize (for example) gets changed. Note that this
makes people who don't use strange cases pay some performance penalty.
Now, this has to be too much hair for this problem. Maybe Kempf's
idea is right. Maybe we don't want to expose all of this for specialization.
If I had some idea what piece of code Danny and Gregor wanted to write, I
could think about this more clearly.
-rpg-
∂07-Apr-88 1917 Common-Lisp-Object-System-mailer Re: (re)initialization revisited
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 7 Apr 88 19:17:09 PDT
Received: from Semillon.ms by ArpaGateway.ms ; 07 APR 88 19:14:43 PDT
Date: Thu, 7 Apr 88 19:14 PDT
From: Gregor.pa@Xerox.COM
Subject: Re: (re)initialization revisited
To: kempf@Sun.COM
cc: common-lisp-object-system@SAIL.STANFORD.EDU
Fcc: BD:>Gregor>mail>outgoing-mail-2.text
In-Reply-To: <8804071913.AA01613@suntana.sun.com>
Message-ID: <880407191422.6.GREGOR@SPIFF.parc.xerox.com>
Line-fold: no
The problem I have with your proposal is that as I see it, the four
concepts are really different concepts. I think it would be a mistake
to combine them.
Even though programmers don't call class-changed or
update-instance-structure, it is easy to imagine that a programmer would
want to do a different thing to an instance in these two cases. The
cases really are different and programs will want to be sensitive to
that difference.
There is of course a lot of similarity. The major thrust of the
proposal Danny and I mailed out was to point out the similarity in their
behavior and isolate it in a common subroutine. All the stuff about the
flags and stuff is secondary. I don't think any further collapsing of
these concepts will be a good idea though.
-------
∂07-Apr-88 1917 Common-Lisp-Object-System-mailer Reinitialization
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 7 Apr 88 19:17:19 PDT
Received: from Semillon.ms by ArpaGateway.ms ; 07 APR 88 19:15:59 PDT
Date: Thu, 7 Apr 88 19:15 PDT
From: Gregor.pa@Xerox.COM
Subject: Reinitialization
To: Dick Gabriel <RPG@SAIL.STANFORD.EDU>
cc: common-lisp-object-system@SAIL.STANFORD.EDU
Fcc: BD:>Gregor>mail>outgoing-mail-2.text
In-Reply-To: The message of 7 Apr 88 14:51 PDT from Dick Gabriel
<RPG@SAIL.Stanford.EDU>
Message-ID: <880407191538.7.GREGOR@SPIFF.parc.xerox.com>
Line-fold: no
After talking to Dick about it in person and having my misunderstanding
clarified for me, I am now in favor of his modification of the proposal
Danny and I originally sent out.
-------
∂08-Apr-88 0135 Common-Lisp-Object-System-mailer update-instance-structure
Received: from labrea.Stanford.EDU by SAIL.Stanford.EDU with TCP; 8 Apr 88 01:35:43 PDT
Received: by labrea.Stanford.EDU; Fri, 8 Apr 88 00:35:12 PST
Received: from bhopal.lucid.com by edsel id AA05945g; Fri, 8 Apr 88 01:28:52 PDT
Received: by bhopal id AA04226g; Fri, 8 Apr 88 01:29:41 PDT
Date: Fri, 8 Apr 88 01:29:41 PDT
From: Jon L White <edsel!jonl@labrea.Stanford.EDU>
Message-Id: <8804080829.AA04226@bhopal.lucid.com>
To: Gregor.pa@xerox.com
Cc: common-lisp-object-system@sail.stanford.edu
In-Reply-To: Gregor.pa@Xerox.COM's message of Mon, 4 Apr 88 16:20 PDT <880404162009.9.GREGOR@SPIFF.parc.xerox.com>
Subject: update-instance-structure
re: In the examples section. I believe the defmethod of
update-instance-structure should be at the end of the example. Even
though this code might work interpreted (in some implementations) it
definitely won't compile. This is because setf of position-rho is used
before position-rho is defined.
Will this still be the case after the "cleanup" proposal for setf-functions
is adopted? I thought one of the two main advantages is that you can assume
a particular function name for doing the SETF, regardless of whether or not it
or the accessor function is "defined".
-- JonL --
∂08-Apr-88 0548 Common-Lisp-Object-System-mailer Re: CLOS, and slot hiding.
Received: from XX.LCS.MIT.EDU by SAIL.Stanford.EDU with TCP; 8 Apr 88 05:48:19 PDT
Received: from LIVE-OAK.LCS.MIT.EDU by XX.LCS.MIT.EDU via Chaosnet; 8 Apr 88 08:46-EDT
Received: from ACORN.Gold-Hill.DialNet.Symbolics.COM by MIT-LIVE-OAK.DialNet.Symbolics.COM via DIAL with SMTP id 86556; 8 Apr 88 08:44:59-EDT
Received: from BOSTON.Gold-Hill.DialNet.Symbolics.COM by ACORN.Gold-Hill.DialNet.Symbolics.COM via CHAOS with CHAOS-MAIL id 98344; Thu 7-Apr-88 08:42:09-EST
Date: Fri, 8 Apr 88 08:41 est
From: mike%acorn@oak.lcs.mit.edu (mike@gold-hill.com any day now)
COMMENTS: NOTE %acorn@oak... WILL BECOME @GOLD-HILL.COM ANY DAY NOW
To: kempf@Sun.COM
Subject: Re: CLOS, and slot hiding.
Cc: mike%acorn@oak.lcs.mit.edu,
common-lisp-object-system@sail.stanford.edu, sidney@XX.LCS.MIT.EDU,
ariel@oz.ai.mit.edu
Date: Wed, 06 Apr 88 09:30:08 -0700
From: kempf@Sun.COM
>If the package system is really the only way to do this, then there
>is really a deep flaw in CLOS. It doesn't support classes for
>data-abstraction very well at all. Was this issue every discussed
>in the design of CLOS?
I think you have this backwards. The flaw (if any) is not in CLOS but
in Common Lisp. The charter of the CLOS committee was to design an
object-oriented extension to Common Lisp, not to "fix" Common Lisp.
Common Lisp deals with modularity using name spaces, packages being
one method of establishing a name space. If the extension were to
Scheme, then environments would be used for establishing the modularity
needed for data abstraction. Extending any language for object-oriented
programming requires that the fundamental abstraction principles of
the language be used and compatibility extended, otherwise the extension
becomes unworkable.
I don't think that common lisp has any particular flaw in this area.
To separate global objects, like specvars, you have to
use packages. Local variables and functions can be separated using
lexical closures.
My dispute is with the nature of instance variables. In the current
CLOS proposal, they get treated in a manner more analogous to
CL's special vars than to local variables. You have to use symbol
naming at the user level to separate them, i.e., either gensymming
or packages.
You want to use the same name but have it mean something different? I'm
confused, sorry. Do you have an example?
Here's a simple one. Everything described here is in the same package.
I have a class, MOVING-OBJECT, with two instance vars RHO and THETA,
used by the method MOVE, defined for MOVING-OBJECT as an update to
the RHO and THETA vars.
I tell my associates about the class MOVING-OBJECT, and the method
MOVE. He defines a subclass AIRPLANE. He wants to use the method
MOVE on instances of AIRPLANE, but he also wants to define methods
BANK and TURN, involving tilting and turning of the conceptual
airplane with respect to level. He wants to use instance variables
RHO and THETA to represent angles of tilt and turn.
He cannot use these names because the class MOVING-OBJECT already
has these names. Unfortunately, since he didn't need to know the
implementation of the MOVE method, he didn't know that there
were already instance vars named RHO and THETA.
Note that the desired behavior is not like CLOS's "local" slots, but
might be called "class specific" slots. These slots exist in
all instances of the class and subclass, but their names are
available only to methods defined on the specific class that
they are created in.
...mike beckerle
∂08-Apr-88 0638 Common-Lisp-Object-System-mailer Re: CLOS, and slot hiding.
Received: from XX.LCS.MIT.EDU by SAIL.Stanford.EDU with TCP; 8 Apr 88 06:38:13 PDT
Received: from LIVE-OAK.LCS.MIT.EDU by XX.LCS.MIT.EDU via Chaosnet; 8 Apr 88 09:31-EDT
Received: from ACORN.Gold-Hill.DialNet.Symbolics.COM by MIT-LIVE-OAK.DialNet.Symbolics.COM via DIAL with SMTP id 86563; 8 Apr 88 09:28:45-EDT
Received: from BOSTON.Gold-Hill.DialNet.Symbolics.COM by ACORN.Gold-Hill.DialNet.Symbolics.COM via CHAOS with CHAOS-MAIL id 98350; Thu 7-Apr-88 09:11:40-EST
Date: Fri, 8 Apr 88 09:11 est
From: mike%acorn@oak.lcs.mit.edu (mike@gold-hill.com any day now)
COMMENTS: NOTE %acorn@oak... WILL BECOME @GOLD-HILL.COM ANY DAY NOW
To: Bobrow.pa@Xerox.COM
Subject: Re: CLOS, and slot hiding.
Cc: mike%acorn@LIVE-OAK.LCS.MIT.EDU, kempf@Sun.COM,
common-lisp-object-system@sail.stanford.edu,
sidney@LIVE-OAK.LCS.MIT.EDU, ariel@oz.ai.mit.edu
Date: 6 Apr 88 10:40 PDT
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
>I agree with the comments made by Moon about the design goals of
>CLOS. Alan Snyder made a big pitch for having encapsulation be an
>important goal for the Common Lisp community, and it was rejected.
>One reason is that it was hard (as Moon mentioned) and another is
>because it does not fit into the philosophy of Lisp, which has always
>prided itself on being an open system (this is the point that Jim
>made so well).
Frankly, I think we should eliminate lexical scoping then and all go
back to using global special vars and functions everywhere. After
all, we want an "open" system. Now seriously. Abstraction features
that are useful and allow programmers to easily practice useful
information hiding are in no way opposed to "open" systems. The two
concepts are utterly orthogonal. I don't want to prevent people who
want to know how my classes are implemented from finding out. I just
dont want them to HAVE to find out in order to use my class as a
superclass. I especially don't want them to find out the hard way, by
having their methods interact with superclass methods in an obscure
manner.
So much for the "open" philosophy issue. As for it being "hard" to implement,
this may be a legitimate objection; however, lots of things in
CLOS are "hard" to implement in both the sense of semantically difficult
to achieve correctness, and in terms of required run-time inefficiency.
Is there some horrible interaction that a class-specific slot option
would have with other aspects of CLOS semantics which I am overlooking?
My intuition is that a change to with-slots would provide the necessary
semantics, and that it could be implemented via the SYMBOL-MACROLET
facility and some gensymming.
...mike beckerle
∂08-Apr-88 0849 Common-Lisp-Object-System-mailer Re: (re)initialization revisited
Received: from Sun.COM by SAIL.Stanford.EDU with TCP; 8 Apr 88 08:49:43 PDT
Received: from snail.sun.com by Sun.COM (4.0/SMI-4.0)
id AA21479; Fri, 8 Apr 88 08:48:49 PDT
Received: from suntana.sun.com by snail.sun.com (4.0/SMI-3.2)
id AA17091; Fri, 8 Apr 88 08:48:19 PDT
Received: from localhost by suntana.sun.com (3.2/SMI-3.2)
id AA02698; Fri, 8 Apr 88 08:41:38 PDT
Message-Id: <8804081541.AA02698@suntana.sun.com>
To: Gregor.pa@Xerox.COM
Cc: common-lisp-object-system@SAIL.STANFORD.EDU
Subject: Re: (re)initialization revisited
In-Reply-To: Your message of Thu, 07 Apr 88 19:14:00 -0700.
<880407191422.6.GREGOR@SPIFF.parc.xerox.com>
Date: Fri, 08 Apr 88 08:41:36 -0700
From: kempf@Sun.COM
>Even though programmers don't call class-changed or
>update-instance-structure, it is easy to imagine that a programmer would
>want to do a different thing to an instance in these two cases. The
>cases really are different and programs will want to be sensitive to
>that difference.
I'd like to see a specific example. To justify having four functions, two
of which have different interfaces but do essentially the same thing and
two of which have the same interface but do the same thing except for
calling one function (possibly, if that hasn't been dropped) you would
want to have them be useful in a large number of cases. The fact that
an additional level is being proposed which essentially unifies all
four suggests to me that the number of cases probably won't be that
large.
The difference between changing the instance structure from an old class
definition to a new, or from one class to another is slight. In both
cases, the common ground is changing the instance structure due to a change
in class. Programmers
that want to do something different in the latter case can specialize
change-class and the reinitialize method to get specialized behavior,
including setting flags or special functions around an invocation of
call-next-method to get specialized behavior because they are in
change-class. Likewise for update-instance-structure. This would throw the
burden of dealing with corner cases on the programmer, rather than trying
to anticipate what the programmer wants and making it part of the language
design.
jak
∂08-Apr-88 0924 Common-Lisp-Object-System-mailer Re: CLOS, and slot hiding.
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 8 Apr 88 09:24:33 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 378468; Fri 8-Apr-88 12:23:32 EDT
Date: Fri, 8 Apr 88 12:23 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: CLOS, and slot hiding.
To: "mike@gold-hill.com any day now" <mike%acorn@oak.lcs.mit.edu>
cc: Bobrow.pa@Xerox.COM, kempf@Sun.COM, common-lisp-object-system@SAIL.STANFORD.EDU,
sidney@LIVE-OAK.LCS.MIT.EDU, ariel@oz.ai.mit.edu
In-Reply-To: The message of 8 Apr 88 10:11 EDT from "mike@gold-hill.com any day now" <mike%acorn@oak.lcs.mit.edu>
Message-ID: <19880408162339.7.MOON@EUPHRATES.SCRC.Symbolics.COM>
Line-fold: No
Date: Fri, 8 Apr 88 09:11 est
From: mike%acorn@oak.lcs.mit.edu (mike@gold-hill.com any day now)
So much for the "open" philosophy issue. As for it being "hard" to implement,
No one said anything it being or not being hard to implement. The issue is that
it is hard to design. There are complicated issues which would have to be
resolved. A standardization committee is the wrong place to do the research
to resolve those issues. My gut feeling is that once there was a design, it would
not be especially difficult to implement, but since I don't know what the design
is, that's only a feeling.
∂08-Apr-88 0950 Common-Lisp-Object-System-mailer Re: Method-lambda and apply-method-lambda
Received: from ti.com by SAIL.Stanford.EDU with TCP; 8 Apr 88 09:50:23 PDT
Received: by ti.com id AA28504; Fri, 8 Apr 88 11:48:07 CDT
Received: from dsg by tilde id AA20268; Fri, 8 Apr 88 11:06:23 CDT
Received: From Jenner By dsg Via CHAOS-NET With CHAOS-MAIL; Mon, 4 Apr 88 07:13:29 CDT
Message-Id: <2785148209-6123016@Jenner>
Date: Mon, 4 Apr 88 07:16:49 CDT
From: Patrick H Dussud <DUSSUD@Jenner.csc.ti.com>
To: Gregor.pa@XEROX.COM
Cc: Common-lisp-object-system@SAIL.STANFORD.EDU
Subject: Re: Method-lambda and apply-method-lambda
In-Reply-To: Msg of Mon, 28 Mar 88 11:35 PST from Gregor.pa@XEROX.COM
Date: Mon, 28 Mar 88 11:35 PST
From: Gregor.pa@XEROX.COM
Subject: Method-lambda and apply-method-lambda
Date: Fri, 25 Mar 88 14:38:09 CST
From: Patrick H Dussud <DUSSUD@Jenner.csc.ti.com>
I have two kinds of comments about your proposal. I have some minor
comments about the details of the proposal itself as well as some
serious questions about whether it can work.
I will start with the minor nits.
make-method-function GENERIC-FUNCTION QUALIFIERS SPECIALIZERS
LAMBDA-FORM &optional MACROEXPAND-ENVIRONMENT
Since, as you say, the method function captures the contract between a
class of generic function and a class of method, I think this generic
function should receive the prototype method as an argument as well.
I am not sure that I want to have to pass the method to apply-method?
If I am going to pass the method, why don't I also pass the generic
function?
Good idea. I didn't put a method in there because I was under the impression
that the modularity of the contract is broken. The way compute-effective-method
is designed, the contract between the generic function and the method, abstracted
by the local macro call-method will not depend on the method. Maybe I didn't
look hard enough.
Also, I am pretty sure we want to make compile work on these, which
brings me to my second point.
How does one write the following code in your proposal:
(defun advise-1-arg-method (method)
(let ((function (method-function method)))
(reinitialize-instance method
:function #'(method-lambda (a)
(format *trace-output* "~&Got arg ~S" a)
(funcall function a)))))
You can do:
(defun advise-1-arg-method (method)
(let ((function (method-function method)))
(reinitialize-instance method
:function
(make-method-function
(method-generic-function method)
(method-qualifiers method)
(method-parameter-specializers method)
`(lambda (a)
(format *trace-output* "~&Got arg ~S" a)
(funcall ,function a)))lambda-form )))
The point is that in this case the `method function lambda' appears
lexically in the source code. That means that it can capture the
lexical variable function. It also means that it is compiled at
compile-file time.
I see your point, but the problem is that you can't decide at compile time what
will be the implementation of the abstraction without knowing anything about the
class of generic function, or the method.
The problem with make-method-function being a function instead of a macro is
that even if all of[ GENERIC-FUNCTION QUALIFIERS SPECIALIZERS ] were known at
compile time and constant, we couldn't do the closure you had in mind.
If this is seen as a problem, we could make make-method-function be a macro
that evaluates GENERIC-FUNCTION QUALIFIERS SPECIALIZERS at macroexpand time then
calls the generic function:
Expand-method-function GENERIC-FUNCTION QUALIFIERS SPECIALIZERS
LAMBDA-FORM &optional MACROEXPAND-ENVIRONMENT
which produces something like:
(function (lambda ....)). Note that what it produces is implementation dependent
and can substitute lambda for something else.
Note that your example does not work anyway. You call the original method
function, but the continuation (a representation of the next-methods list) is
lost in the process. I am sure that we need something, like a local macro
defined inside of the expanded method function, that allows someone to get at
the continuation, and then pass it to apply-method-function. I'll have to think
more about it.
Patrick.
∂08-Apr-88 1002 Common-Lisp-Object-System-mailer Re: Method-lambda and apply-method-lambda
Received: from ti.com by SAIL.Stanford.EDU with TCP; 8 Apr 88 10:02:31 PDT
Received: by ti.com id AA28671; Fri, 8 Apr 88 12:00:15 CDT
Received: from dsg by tilde id AA21572; Fri, 8 Apr 88 11:53:02 CDT
Received: From Jenner By dsg Via CHAOS-NET With CHAOS-MAIL; Tue, 5 Apr 88 08:52:50 CDT
Message-Id: <2785240766-146050@Jenner>
Date: Tue, 5 Apr 88 08:59:26 CDT
From: Patrick H Dussud <DUSSUD@Jenner.csc.ti.com>
To: Gregor.pa@XEROX.COM
Cc: Common-lisp-object-system@SAIL.STANFORD.EDU
Subject: Re: Method-lambda and apply-method-lambda
Return-Path: <DUSSUD@Jenner>
Received: From Jenner By dsg Via CHAOS-NET With CHAOS-MAIL; Thu, 31 Mar 88 15:46:20 CST
Message-Id: <2784836687-3921370@Jenner>
Date: Thu, 31 Mar 88 15:44:47 CST
From: Patrick H Dussud <DUSSUD@Jenner>
To: Gregor.pa@XEROX.COM
Cc: Common-lisp-object-system@SAIL.STANFORD.EDU
Subject: Re: Method-lambda and apply-method-lambda
In-Reply-To: Msg of Mon, 28 Mar 88 11:35 PST from Gregor.pa@XEROX.COM
Date: Mon, 28 Mar 88 11:35 PST
From: Gregor.pa@XEROX.COM
Subject: Method-lambda and apply-method-lambda
Date: Fri, 25 Mar 88 14:38:09 CST
From: Patrick H Dussud <DUSSUD@Jenner.csc.ti.com>
I have two kinds of comments about your proposal. I have some minor
comments about the details of the proposal itself as well as some
serious questions about whether it can work.
I will start with the minor nits.
make-method-function GENERIC-FUNCTION QUALIFIERS SPECIALIZERS
LAMBDA-FORM &optional MACROEXPAND-ENVIRONMENT
Since, as you say, the method function captures the contract between a
class of generic function and a class of method, I think this generic
function should receive the prototype method as an argument as well.
I am not sure that I want to have to pass the method to apply-method?
If I am going to pass the method, why don't I also pass the generic
function?
Good idea. I didn't put a method in there because I was under the impression
that the modularity of the contract is broken. The way compute-effective-method
is designed, the contract between the generic function and the method, abstracted
by the local macro call-method will not depend on the method. Maybe I didn't
look hard enough.
Also, I am pretty sure we want to make compile work on these, which
brings me to my second point.
How does one write the following code in your proposal:
(defun advise-1-arg-method (method)
(let ((function (method-function method)))
(reinitialize-instance method
:function #'(method-lambda (a)
(format *trace-output* "~&Got arg ~S" a)
(funcall function a)))))
You can do:
(defun advise-1-arg-method (method)
(let ((function (method-function method)))
(reinitialize-instance method
:function
(make-method-function
(method-generic-function method)
(method-qualifiers method)
(method-parameter-specializers method)
`(lambda (a)
(format *trace-output* "~&Got arg ~S" a)
(funcall ,function a)))lambda-form )))
The point is that in this case the `method function lambda' appears
lexically in the source code. That means that it can capture the
lexical variable function. It also means that it is compiled at
compile-file time.
I see your point, but the problem is that you can't decide at compile time what
will be the implementation of the abstraction without knowing anything about the
class of generic function, or the method.
The problem with make-method-function being a function instead of a macro is
that even if all of[ GENERIC-FUNCTION QUALIFIERS SPECIALIZERS ] were known at
compile time and constant, we couldn't do the closure you had in mind.
If this is seen as a problem, we could make make-method-function be a macro
that evaluates GENERIC-FUNCTION QUALIFIERS SPECIALIZERS at macroexpand time then
calls the generic function:
Expand-method-function GENERIC-FUNCTION QUALIFIERS SPECIALIZERS
LAMBDA-FORM &optional MACROEXPAND-ENVIRONMENT
which produces something like:
(function (lambda ....)). Note that what it produces is implementation dependent
and can substitute lambda for something else.
Note that your example does not work anyway. You call the original method
function, but the continuation (a representation of the next-methods list) is
lost in the process. I am sure that we need something, like a local macro
defined inside of the expanded method function, that allows someone to get at
the continuation, and then pass it to apply-method-function. I'll have to think
more about it.
Patrick.
∂08-Apr-88 1044 Common-Lisp-Object-System-mailer comments on CLOS draft 88-2
Received: from XX.LCS.MIT.EDU by SAIL.Stanford.EDU with TCP; 8 Apr 88 10:44:11 PDT
Received: from LIVE-OAK.LCS.MIT.EDU by XX.LCS.MIT.EDU via Chaosnet; 8 Apr 88 13:42-EDT
Received: from ACORN.Gold-Hill.DialNet.Symbolics.COM by MIT-LIVE-OAK.DialNet.Symbolics.COM via DIAL with SMTP id 86604; 8 Apr 88 13:40:59-EDT
Received: from BOSTON.Gold-Hill.DialNet.Symbolics.COM by ACORN.Gold-Hill.DialNet.Symbolics.COM via CHAOS with CHAOS-MAIL id 98371; Thu 7-Apr-88 13:14:50-EST
Date: Fri, 8 Apr 88 13:13 est
From: mike%acorn@oak.lcs.mit.edu (mike@gold-hill.com any day now)
COMMENTS: NOTE %acorn@oak... WILL BECOME @GOLD-HILL.COM ANY DAY NOW
To: common-lisp-object-system@sail.stanford.edu
Subject: comments on CLOS draft 88-2
cc: mike
Our (Gold Hill's) mail link will be disappearing shortly for about
two weeks, so I wanted to get out these last comments for
your consideration in the next CLOS spec draft.
This has nothing to do with instance-variable names by the way. :-)
...Mike Beckerle
Gold Hill
-------------------------------------------------------------
More (but different) Comments on the CLOS specification 88-02:
I am generally pleased with the detail level of the new draft. It
nails down the semantics of CLOS much more clearly than CLtL does for
most of CL. Nevertheless, there is one aspect of the spec that I
think should be changed before adoption as a preliminary standard.
This has to do with overspecification of the amount of dynamic
redefinition possible in CLOS programs.
All material having to do with the behavior of instances when classes
are redefined should be omitted. Common Lisp implementations should
not be required to update instances when classes are redefined.
The spec should separate "language" issues from "environment" issues
here and specify only the behavior of whole programs, not of
environments that have been subjected to any number of redefinitions
and changes. I do not deny that it is convenient when developing a program
to have dynamic redefinition of classes; however, the common lisp spec
should be for a language first and an environment second.
In particular, the material in pages 1-15 through 1-18 of the
"Programmer Interface Concepts" part should be deleted. The behavior
of instances when classes are redefined should not be specified.
Specification of these kind of behaviors in CLtL is very weak, and
is frequently the source of significant disagreement on the
behavior of otherwise simple language constructs. We should not
carry on the tradition in CLtL of specifying how programs behave in
the face of redefinition or a dynamically changing execution
environment.
The following are the operations from the "Functions in the Programmer
Interface" that I think should be removed.
UPDATE-INSTANCE-STRUCTURE
MAKE-INSTANCES-OBSOLETE
CHANGE-CLASS,
CLASS-CHANGED
CMAKUNBOUND
CBOUNDP
The other alternative is for these symbols to name optional components
of CLOS which are not required to work in all implementations, but if
they do, they use these standard names and have this standard
functionality.
∂08-Apr-88 1102 Common-Lisp-Object-System-mailer comments on CLOS draft 88-2
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 8 Apr 88 11:01:56 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via INTERNET with SMTP id 378569; 8 Apr 88 14:01:34 EDT
Date: Fri, 8 Apr 88 14:01 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: comments on CLOS draft 88-2
To: "mike@gold-hill.com any day now" <mike%acorn@oak.lcs.mit.edu>
cc: common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: The message of 8 Apr 88 14:13 EDT from "mike@gold-hill.com any day now" <mike%acorn@oak.lcs.mit.edu>
Message-ID: <19880408180143.1.MOON@EUPHRATES.SCRC.Symbolics.COM>
I agree that it would be a good idea to define a standard run-time (i.e.
non-development) subset of Common Lisp. I don't think CLOS is the only
area where features would be deleted to create this subset. For some
reason it's been very difficult to recruit volunteers to propose the
details of this.
By the way, I'm not sure it's desirable to omit CHANGE-CLASS from a
run-time subset. This is not really a development operation, some
application programs do it.
∂08-Apr-88 1142 Common-Lisp-Object-System-mailer Re: comments on CLOS draft 88-2
Received: from Sun.COM by SAIL.Stanford.EDU with TCP; 8 Apr 88 11:42:13 PDT
Received: from snail.sun.com by Sun.COM (4.0/SMI-4.0)
id AA24564; Fri, 8 Apr 88 11:40:15 PDT
Received: from suntana.sun.com by snail.sun.com (4.0/SMI-3.2)
id AA23681; Fri, 8 Apr 88 11:39:50 PDT
Received: from localhost by suntana.sun.com (3.2/SMI-3.2)
id AA02977; Fri, 8 Apr 88 11:33:10 PDT
Message-Id: <8804081833.AA02977@suntana.sun.com>
To: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Cc: "mike@gold-hill.com any day now" <mike%acorn@oak.lcs.mit.edu>,
common-lisp-object-system@SAIL.STANFORD.EDU
Subject: Re: comments on CLOS draft 88-2
In-Reply-To: Your message of Fri, 08 Apr 88 14:01:00 -0400.
<19880408180143.1.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Fri, 08 Apr 88 11:33:08 -0700
From: kempf@Sun.COM
I also agree with Dave and Mike on this issue, except I'm not sure about
CHANGE-CLASS. Certainly, some way of getting a minimal subset would
make pushing CLOS more deeply into CL implementations more palatable.
I'm not sure, however, if it's possible at this late a date to do
so. It could probably be factored into a Chapter 2.5, between
the Metaobject Protocol and the Programmer Interface, and be
called something like "Environment Hooks", though hooks probably
isn't the right word.
jak
∂08-Apr-88 1148 Common-Lisp-Object-System-mailer Re: comments on CLOS draft 88-2
Received: from WILMA.BBN.COM ([128.89.1.216]) by SAIL.Stanford.EDU with TCP; 8 Apr 88 11:47:58 PDT
To: "mike@gold-hill.com any day now" <mike%acorn@live-oak.lcs.mit.edu>
cc: common-lisp-object-system@sail.stanford.edu, mike@LIVE-OAK.LCS.MIT.EDU
Subject: Re: comments on CLOS draft 88-2
In-reply-to: Your message of Fri, 08 Apr 88 13:13:00 -0500.
Date: Fri, 08 Apr 88 14:46:28 -0400
From: kanderso@WILMA.BBN.COM
>The following are the operations from the "Functions in the Programmer
>Interface" that I think should be removed.
>UPDATE-INSTANCE-STRUCTURE
>MAKE-INSTANCES-OBSOLETE
>CHANGE-CLASS,
>CLASS-CHANGED
I think the first 4 of the above list belong together as they are a
protocol for what happens to instances when a class changes. I agree
that dynamically changing things should be optional. Since it is a
metaclass issue, the metaclass protocols should allow this behavior to
be added as an optional meta class mixin wheter it is in CLOS spec or
not.
>CMAKUNBOUND
>CBOUNDP
These deal with adding and deleteing classes and i don't see how CLOS
could live without them. Some kind of dynamic behvior is very nice.
I would hate to have to reboot every time i make a mistake.
k
∂08-Apr-88 1152 Common-Lisp-Object-System-mailer add-named-xxx
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 8 Apr 88 11:52:44 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 378631; Fri 8-Apr-88 14:52:09 EDT
Date: Fri, 8 Apr 88 14:52 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: add-named-xxx
To: Gregor.pa@Xerox.COM
cc: common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: <880404112029.5.GREGOR@SPIFF.parc.xerox.com>
Message-ID: <19880408185223.5.MOON@EUPHRATES.SCRC.Symbolics.COM>
Line-fold: No
Date: Mon, 4 Apr 88 11:20 PDT
From: Gregor.pa@Xerox.COM
At our last meeting, there was some sentiment for making the behavior of
add-named-class, ensure-generic-function and add-named-method more
uniform. This message attempts to address those issues.
I have spent some time thinking about this, and I still feel that while
add-named-class and ensure-generic-function are similar, add-named-method
is different.
One way to see this is to think about the defining forms which these
functions are the analog of. add-named-class is the analog of defclass;
ensure-generic-function is the analog of defgeneric; add-named-method is
the analog of defmethod.
defclass and defgeneric each provide a way to specify the class of the
metaobject created....
On the other hand, defmethod provides no mechanism for controlling the
class of the generic function or the method it creates. For this reason
it doesn't make sense for add-named-method to have that ability.
Wait a minute. I thought the only reason defmethod didn't allow one to
specify the class of the method is that there is no good place to stick it
in the syntax. I could easily imagine someone defining an alternate version
of defmethod, with different syntax, that allowed the method class to be
specified. They would be chagrined if they could not use add-named-method
to implement this macro, but had to make an unmodular copy of the body of
add-named-method in order to do it.
Are you saying that it is fundamentally wrong to specify the class of
the method object when defining a method? I admit that I've only seen
one application of this, in a paper from some folks at BBN who were
using PCL, and what they were doing was confused (they didn't want meta
objects at all, just plain Lisp macros). However I assume that use of
method meta object classes does make sense sometimes and that specifying
the class when defining a method does make sense sometimes.
On the other hand, it is possible to make add-named-method a little more
uniform by having it take keyword arguments which get passed on to the
make-instance of the method.
(defun add-named-method (generic-function-name &rest keys
&key qualifiers
specializers
&allow-other-keys)
(let* ((gf (ensure-generic-function
(class-prototype (class-named 'standard-generic-function))
:name generic-function-name))
(new-method (apply #'make-instance
(generic-function-method-class gf)
keys))
(old-method (get-method gf qualifiers specializers)))
(when old-method (remove-method gf old-method))
(add-method gf new-method)))
An alternate proposal would be to give the caller of add-named-method
more control over the arguments passed to ensure-generic-function. My
feeling is that it isn't worth cluttering up add-named-method to do
that. If someone wants more control over the arguments to
ensure-generic-function they can call it directly.
After thinking about the above three paragraphs a bit, I think this is
wrong modularity, by your own arguments. I think the caller of
add-named-method should -always- call ensure-generic-function himself.
That is, defmethod really consists of two parts, defining the generic
function if not already defined, and defining/replacing the method.
These two parts should not be combined in the macro expansion. Thus
the arguments to add-named-method should be a prototype method (the
usual kludge for class-discriminating methods) and some keyword arguments
that include a generic function object, qualifiers, specializers, the
method function, and some others that are optional.
The way that add-named-method -is- different from add-named-class and
add-named-generic-function (ahem) is that add-named-method doesn't have
a symbol as a name, instead the conceptual name (something that
identifies a prior object to be replaced) is composed of the generic
function, the specializers, and the qualifiers. That difference is
inherent, but the other differences in your most recent draft are
accidental and should be eliminated. I think this is the reasoning
behind the sentiment for making these things more uniform.
Does this make sense to you?
∂08-Apr-88 1211 Common-Lisp-Object-System-mailer Re: Reinitialization
Received: from Sun.COM by SAIL.Stanford.EDU with TCP; 8 Apr 88 12:11:23 PDT
Received: from snail.sun.com by Sun.COM (4.0/SMI-4.0)
id AA25083; Fri, 8 Apr 88 12:10:27 PDT
Received: from suntana.sun.com by snail.sun.com (4.0/SMI-3.2)
id AA24828; Fri, 8 Apr 88 12:09:47 PDT
Received: from localhost by suntana.sun.com (3.2/SMI-3.2)
id AA03057; Fri, 8 Apr 88 12:03:02 PDT
Message-Id: <8804081903.AA03057@suntana.sun.com>
To: Dick Gabriel <RPG@SAIL.Stanford.EDU>
Cc: common-lisp-object-system@SAIL.Stanford.EDU
Subject: Re: Reinitialization
In-Reply-To: Your message of 07 Apr 88 14:51:00 -0700.
<8804072155.AA10716@Sun.COM>
Date: Fri, 08 Apr 88 12:03:00 -0700
From: kempf@Sun.COM
Yow! That *was* pretty hairy.
Well, anywy, my observations on the matter are the following:
1) 99% of the people using CLOS won't be interested in customizing
(re)initialization anyway,
2) Of the 1% that are, maybe 80% will need the fine distinctions
that the current interface provides.
So putting in 4 functions just so .8% of the people who use CLOS don't
have to go through extra hair doesn't make much sense to me.
Not to speak of the hair in your note.
Here's what I had in mind. Let's say Joe MetaObject User wants to
specialize in such a way that, indeed, some distinction between
an instance changing due to a class redefinition and due to a
CHANGE-CLASS call are distinguished. Then the following code
should do it:
(defmethod change-class ((instance joes-class) new-class)
(with-added-methods
(reinitialize ((object joes-class) &rest reinit-args)
<code to deal with changes in this case, perhaps including
call-next-method>
)
<code to deal with what Joe wants, including perhaps call-next-method
(apply #'reinitialize instance joes-reinit-args)
<further specific code>
)
)
Now, let's say Joe wants to change around how instances are reinitialized
when a change is made through redefinition of a class. This is
somewhat trickier, but still possible:
(defmethod reinitialize ((object joes-class) &rest reinit-args)
<do something to reinitialize when the class definition is changed>
)
(defmethod change-class ((instance joes-class) new-class
(with-added-methods
(reinitialize ((object joes-class) &rest reinit-args)
<code to deal with changes only for class changing>
)
<code to deal with what Joe wants, including perhaps call-next-method>
(apply #'reinitialize instance joes-reinit-args)
<further specific code>
)
)
Are there any other occasions when reinitialize might be called?
One might be that a programmer might want to call it directly.
In that case, its incumbent upon Joe to supply his own method
which does reinitialization according to a scheme for direct
calls, perhaps using a different name or lexically, at the top
level.
In any event, you get the idea. No flags, special variables,
functional arguments, MSG, smoke, or mirrors. Just using the
mechanisms which are already in place to do the job.
jak
∂08-Apr-88 1314 Common-Lisp-Object-System-mailer comments on CLOS draft 88-2
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 8 Apr 88 13:14:36 PDT
Received: from Semillon.ms by ArpaGateway.ms ; 08 APR 88 13:13:01 PDT
Date: Fri, 8 Apr 88 13:12 PDT
From: Gregor.pa@Xerox.COM
Subject: comments on CLOS draft 88-2
To: "mike@gold-hill.com any day now" <mike%acorn@LIVE-OAK.LCS.MIT.EDU>
cc: common-lisp-object-system@SAIL.STANFORD.EDU, mike@LIVE-OAK.LCS.MIT.EDU
Fcc: BD:>Gregor>mail>outgoing-mail-2.text
In-Reply-To: The message of 8 Apr 88 11:13 PDT from "mike@gold-hill.com any day
now" <mike%acorn@LIVE-OAK.LCS.MIT.EDU>
Message-ID: <880408131233.1.GREGOR@SPIFF.parc.xerox.com>
Line-fold: no
I believe that the philosopy behind the suggestion is a good one, but I
don't think this particular instance applies.
The reason is that I don't see instance updating as a development
environment only issue -- the reason we put updating in was that we
didn't see it as a development environment only issue.
Imagine a piece of product code which defines a bunch of classes, call
it Product1. Now imagine another product which is an extension to the
first product, call that Product2. It is reasonable to assume that
Product2 will want to modify some aspects of Prodcut1. Specifically,
Product2 may want to modify some of Product1's class definitions. The
instance update protocol is designed to make this kind of scenario
workable. I think having this kind of flexibility is going to be real
important to unbundled products which use CLOS.
Another important point is that the CLOS committee understands the cost
of having this kind of flexibility quite well. It is minimal. I don't
think that this feature complicates the implementation of CLOS
significantly.
-------
∂08-Apr-88 1514 Common-Lisp-Object-System-mailer method-lambda and apply-method-lambda
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 8 Apr 88 15:14:14 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 378864; Fri 8-Apr-88 18:13:57 EDT
Date: Fri, 8 Apr 88 18:14 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: method-lambda and apply-method-lambda
To: common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: <880115131101.2.GREGOR@SPIFF.parc.xerox.com>,
<2784314289-5590063@Jenner>,
<8803252143.AA03557@suntana.sun.com>,
<2784566339-4218491@Jenner>,
<880328113536.8.GREGOR@SPIFF.parc.xerox.com>,
<2785148209-6123016@Jenner>
Message-ID: <19880408221409.1.MOON@EUPHRATES.SCRC.Symbolics.COM>
I've been thinking about this issue and here's my considered opinion.
Date: Fri, 15 Jan 88 13:11 PST
From: Gregor.pa@Xerox.COM
A problem we have never quite resolved is how to abstract out the
information about call-next-method (and slot optimization) that needs to
be passed to method functions. I have said on several occaisons that I
would like for it to be possible to apply method functions to the
'natural' arguments; I would also like it to be possible to construct
method functions. Moon has countered quite rightly that this makes it
difficult to implement call-next-method.
Briefly I propose that we introduce a constructs called method-lambda
and method-apply.
I strongly agree with these goals. I think we're still searching for the
right constructs to satisfy the goals. I think Patrick is on the right
track, though.
Date: Fri, 25 Mar 88 14:38:09 CST
From: Patrick H Dussud <DUSSUD@Jenner.csc.ti.com>
I don't think that method-lambda, as describe in 88-003 is good enough. It
captures the contract between a class of generic functions and a class of methods,
so it should be metaclass driven. You can imagine several contracts on a single
implementation.
I propose the following:
Make-method-function is a generic function.
make-method-function GENERIC-FUNCTION QUALIFIERS SPECIALIZERS LAMBDA-FORM &optional MACROEXPAND-ENVIRONMENT
The generic function make-method-function returns a function suitable for the
function slot of a method. Its representation is implementation dependent.
I think the -only- assertions guaranteed about the value returned by
MAKE-METHOD-FUNCTION should be:
- COMPILE works on it
- the FUNCTION special form works on it
- it and the result of compiling it are members of the type FUNCTION
- APPLY-METHOD works on it and on the result of compiling it
- it and the result of compiling it can be used as the :method-function
when creating or reinitializing a method meta-object
A plausible implementation technique is for MAKE-METHOD-FUNCTION to return
a list whose car is LAMBDA and whose cdr is implementation-dependent. Other
implementation techniques are also possible.
apply-method METHOD NEXT-METHOD-LIST &rest ARGUMENTS [ generic function]
apply-method is discriminated on METHOD.
METHOD is the method that needs to be invoked.
Using a method meta-object rather than a method-function is an interesting
change. After thinking about it, I agree that this is right. The meta object
encapsulates all the static information that might determine what calling
sequence to use (generic function, specializers, and qualifiers) while the other
arguments to APPLY-METHOD are all the dynamic information that can be needed
for calling a method.
NEXT-METHOD-LIST is the list of all the methods that can be invoked by calling
call-next-method.
There is an interesting question here whether this should be explicitly a list
of method objects, or should be abstracted as some implementation-dependent
object that represents that list.
Date: Fri, 25 Mar 88 13:43:43 -0800
From: kempf@Sun.COM
Why, precisely, do you think there need be any difference between a method
function and any other kind of function? I can understand this for
a generic function, since a generic function has slots, but a method
function has none. It seems to me that most of how a method function
differs is covered by additions to its lexical environment, and that
FUNCALL and APPLY should do.
Date: Mon, 28 Mar 88 12:38:59 CST
From: Patrick H Dussud <DUSSUD@Jenner.csc.ti.com>
I agree that in structure, a method function is like any other function. However
method functions are getting called with(in) an implementation dependent
environment that must be abstracted from the user. This is the motivation for
the encapsulation (method-lambda, apply-method-lambda) given in chapter 3. The
point of my earlier message is that this encapsulation should be metaclass
dependent.
The things that may be contained in the environment are(among others):
Permutation vector(s), call-next-method list.
This environment is distinct from the lexical environment of a closure. That
does not prevent some implementation to code it as if it were a lexical
environment, but that's an implementation choice.
I agree with Patrick's response here. It can be further clarified by understanding
the difference between static information (always the same for a given method) and
dynamic information. Permutation vector(s) and call-next-method list are dynamic,
they depend on the (classes of the) arguments, thus they cannot be supplied by using
a lexical closure as the method-function.
Date: Mon, 28 Mar 88 11:35 PST
From: Gregor.pa@Xerox.COM
Since, as you say, the method function captures the contract between a
class of generic function and a class of method, I think this generic
function should receive the prototype method as an argument as well.
Agreed.
I am not sure that I want to have to pass the method to apply-method?
If I am going to pass the method, why don't I also pass the generic
function?
No, I think passing the method object is right (see my comment above).
However, you could convince me that apply-method should take all three
of the method-function, the method, and the generic-function. One way to
convince me of this would be to show a case where one wants to call a
method-function that is not the current method-function of any method
(perhaps when tracing).
Also, I am pretty sure we want to make compile work on these
Agreed.
Perhaps the solution is
to have the generic function you say, but specify in addition that the
standard method returns (METHOD-LAMBDA (..) ...).
No, I think it's important to define the -behavior- of what
make-method-function returns, but to leave the -representation-
implementation-dependent. I don't think it's a good idea to introduce
this new symbol that is like LAMBDA. More about this directly below.
Date: Mon, 4 Apr 88 07:16:49 CDT
From: Patrick H Dussud <DUSSUD@Jenner.csc.ti.com>
Date: Mon, 28 Mar 88 11:35 PST
From: Gregor.pa@XEROX.COM
The point is that in this case the `method function lambda' appears
lexically in the source code. That means that it can capture the
lexical variable function. It also means that it is compiled at
compile-file time.
I think both of these are important properties.
I see your point, but the problem is that you can't decide at compile time what
will be the implementation of the abstraction without knowing anything about the
class of generic function, or the method.
Right. I agree that the two properties Gregor proposes sound important,
but I believe that it is impossible to achieve those properties. I think
that the attempt to achieve those properties is why we've been having
trouble converging here. Giving up those properties will make the problem
much easier, and I don't think it means giving up anything that matters.
Another point I want to make is that both Gregor's and Patrick's versions
of advise-1-arg-method [I'll omit repeating the code here] don't work,
because they use FUNCALL on the result of METHOD-FUNCTION. You have to
use APPLY-METHOD, not APPLY or FUNCALL. I assume this was an accident,
not a proposal that FUNCALL should work on these functions.
The problem with make-method-function being a function instead of a macro is
that even if all of[ GENERIC-FUNCTION QUALIFIERS SPECIALIZERS ] were known at
compile time and constant, we couldn't do the closure you had in mind.
If this is seen as a problem, we could make make-method-function be a macro
that evaluates GENERIC-FUNCTION QUALIFIERS SPECIALIZERS at macroexpand time then
calls the generic function
I don't think this is a good idea. If users want to write macros whose expander
functions call make-method-function, they can do that. In fact I think that
will be done often, and I approve of it. make-method-function itself, as a
primitive, should remain a function, not be turned into a macro. I don't think
it's useful to provide a built-in macro version of this, because I think any
macro that calls make-method-function is going to do other things as well.
Note that your example does not work anyway. You call the original method
function, but the continuation (a representation of the next-methods list) is
lost in the process.
-Part- of what I was complaining about with use of FUNCALL.
I am sure that we need something, like a local macro
defined inside of the expanded method function, that allows someone to get at
the continuation, and then pass it to apply-method-function. I'll have to think
more about it.
Agreed. See my comment above on whether the second argument to
APPLY-METHOD should be a list of method objects or something more
abstract.
Here's what I think we should do:
MAKE-METHOD-FUNCTION proto-method generic-function qualifiers specializers
lambda-exp &OPTIONAL macroexpand-environment
and the return value's behavior is defined as I proposed above.
Note that the functions CALL-NEXT-METHOD, NEXT-METHOD-P, and
NEXT-METHOD-INFO [see below] have bindings in a scope that includes
all forms in lambda-exp. *** Note that I am proposing a change here;
88-002 would make the scope include only the body of lambda-exp, but
Flavors users convinced me that that is inconsistent and wrong, and
that default-value forms in the lambda-list must be included in the
scope. The implementation of this is easy. In earlier discussions
I believe it was argued that the implementation is too difficult, but
I think the MAKE-METHOD-FUNCTION proposal reveals that no user needs
to be concerned with the implementation of this scoping, as it is
always done inside of MAKE-METHOD-FUNCTION.
APPLY-METHOD method next-method-info &REST arguments
This is the only way to call the result of MAKE-METHOD-FUNCTION.
method is the meta-object, not the method-function.
As noted above, my mind could be changed on the arguments to this.
NEXT-METHOD-INFO
This is in the same category as CALL-NEXT-METHOD and NEXT-METHOD-P.
The only defined operation on its value is to use it as the second
argument to APPLY-METHOD.
MAKE-NEXT-METHOD-INFO method generic-function list-of-methods
This is a primitive that returns the same kind of abstract value that
NEXT-METHOD-INFO returns, given a concrete list of methods and the
two meta objects that control the method calling sequence.
We could find a better name than "next-method-info". My only comments
on the name are (a) avoid "continuation", it really means something
else, and (b) include the words "next method(s)" in the name to express
the relationship of this to CALL-NEXT-METHOD.
∂08-Apr-88 1540 Common-Lisp-Object-System-mailer Re: (re)initialization revisited
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 8 Apr 88 15:39:43 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 08 APR 88 15:37:13 PDT
Date: 8 Apr 88 15:37 PDT
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Re: (re)initialization revisited
In-reply-to: kempf@Sun.COM's message of Thu, 07 Apr 88 12:13:45 -0700
To: kempf@Sun.COM
cc: common-lisp-object-system@SAIL.STANFORD.EDU
Message-ID: <880408-153713-9540@Xerox>
Jim proposes removing some functions in the spec. I sympathize with this as a
general goal. But in this case I think it is misguided. There are really four
concepts
1) initializate (make a brand new instance have the right state)
2) reinitialize (make an old instance have a "standard" starting state)
3) class-changed (make a change from one form of current instance to another)
4) update-instance-structure (make an appropriate current instance from an
outdated instance.
Because there are four concepts, there must be four entries so that users can
change what is done for each. Collapsing concepts into a commonly named fn just
causes confusion.
For example, in doing class-changed, one can take advantage of methods on the
class-before-change; for example, changing class of p1 from an x-y-point to
rho-theta-point, one can use the methods for rho and theta defined on x-y-point.
There is no class-before-change for update-instance-structure.
Reinititializing must potentially take into account old values on slots.
Initialization never has to. We introduced the general concept because we had
two examples in CLOS itself that require it: instances of standard-class, and
instances of standard-generic-function. Both must take into account previous
state of the objects to be changed.
---
There is commonality of code in the usual case between these four concepts. We
express that common piece as a separate function shared-initialize.
Now the question comes up of what happens if one wants to "slightly" change the
common part. This ability to make a slight change easily is an advertised
feature of object oriented programming. The question comes up, what conditions
can you use to determine the slight change.
The hypothesis in our original proposal was that it was a reasonable thing to
make the slight change depend on who called the common piece. Gregor and I
chose to enable this by making the caller name be an argument of the call. This
supports two different mechanisms for capturing the differences
1) It allows a single method to test the value of the flag. Or to put it
another way, it allows a case statement within the called method to determine
which code is run. This is rather like building generic functions by using case
statements. However, it is appropriate if most of the code is shared, and the
unshared parts are distributed through the code.
2) It supports the definition of individual methods specialized on the caller
symbol. This is appropriate if the usual method must be completely shadowed, or
if the usual method can be surrounded by the desired special case behavior.
RPG suggested passing a functional argument. I mistakenly though that there
would be no way of changing the functional argument in the case of class-changed
and update-instance-structure. Dick pointed out that the way one does this is
to make a special caller that modifies the usual provided initializer functions
and calls the next method. This is elegant provided one can easily make changes
in provided functions. Dick suggested extending with-added-methods to allow
specification of the generic function to be changed, or later by using a special
form to mess with the incoming initializer.
The comparison seems to be between:
RPG code:
Consider:
(defmethod reinitialize-instance ((instance standard-object)
initializer &rest initargs)
<An incredibly hairy mess>
...
(apply initializer instance initargs)
...
<Weirder stuff than a human can imagine>)
Now if we want to alter the behavior of shared-initialize when
called by reinitialize-instance on some more specific class than
standard-object, we do the following:
(defmethod reinitialize-instance ((instance some-class)
initializer &rest initargs)
(with-generic-function-messed-with
(initializer (mess-with-generic-function initializer))
(apply #'call-next-method instance initializer initargs)))
----
Code from DGB/Gregor proposal:
(defmethod reinitialize-instance ((instance standard-object)
&rest initargs)
<An incredibly hairy mess>
...
(shared-initialize instance 'reinitialize-instance initargs)
...
<Weirder stuff than a human can imagine>)
(defmethod shared-initialize ((instance some-class)
(caller (eql 'reinitialize-instance)) &rest initargs)
... whatever messing you like doing
... some more messing )
And there is no "with-generic-function-messed-with" macro to deal with
---
∂09-Apr-88 0337 Common-Lisp-Object-System-mailer add-named-xxx
Received: from labrea.Stanford.EDU by SAIL.Stanford.EDU with TCP; 9 Apr 88 03:36:43 PDT
Received: by labrea.Stanford.EDU; Sat, 9 Apr 88 02:36:15 PST
Received: from bhopal.lucid.com by edsel id AA11444g; Sat, 9 Apr 88 03:13:42 PDT
Received: by bhopal id AA08707g; Sat, 9 Apr 88 03:14:32 PDT
Date: Sat, 9 Apr 88 03:14:32 PDT
From: Jon L White <edsel!jonl@labrea.Stanford.EDU>
Message-Id: <8804091014.AA08707@bhopal.lucid.com>
To: Moon@stony-brook.scrc.symbolics.com
Cc: Gregor.pa@xerox.com, common-lisp-object-system@sail.stanford.edu,
rwk@ai.ai.mit.com, rg@ai.ai.mit.com,
sun!franz!feast!smh@labrea.Stanford.EDU
In-Reply-To: David A. Moon's message of Fri, 8 Apr 88 14:52 EDT <19880408185223.5.MOON@EUPHRATES.SCRC.Symbolics.COM>
Subject: add-named-xxx
re: The way that add-named-method -is- different from add-named-class and
add-named-generic-function (ahem) is that add-named-method doesn't have
a symbol as a name, instead the conceptual name (something that
identifies a prior object to be replaced) is composed of the generic
function, the specializers, and the qualifiers. That difference is
inherent, but the other differences in your most recent draft are
accidental and should be eliminated. . . .
I.e., the "name" for a method isn't a symbol but could be a "definition
spec" (or "function spec" if you will).
Although one might facetiously suggest that
(lambda (x y) (list x y))
is a "conceptual" name for the function
#'(lambda (x y) (list x y))
I think this is stretching the point. On the other hand, having
a name for a method like
(documentation (standard-class)) ;for primary methods
or
(documentation (persistent-class) :before) ;for before methods
is a natural expression of "function specs". [I presume that you
meant "parameter specializer name" when you said "specializers" above].
-- JonL --
∂11-Apr-88 0906 Common-Lisp-Object-System-mailer Re: method-lambda and apply-method-lambda
Received: from Sun.COM by SAIL.Stanford.EDU with TCP; 11 Apr 88 09:06:49 PDT
Received: from snail.sun.com by Sun.COM (4.0/SMI-4.0)
id AA00083; Mon, 11 Apr 88 09:05:47 PDT
Received: from suntana.sun.com by snail.sun.com (4.0/SMI-3.2)
id AA10363; Mon, 11 Apr 88 09:05:14 PDT
Received: from localhost by suntana.sun.com (3.2/SMI-3.2)
id AA05147; Mon, 11 Apr 88 08:58:37 PDT
Message-Id: <8804111558.AA05147@suntana.sun.com>
To: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Cc: common-lisp-object-system@SAIL.STANFORD.EDU
Subject: Re: method-lambda and apply-method-lambda
In-Reply-To: Your message of Fri, 08 Apr 88 18:14:00 -0400.
<19880408221409.1.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Mon, 11 Apr 88 08:58:35 -0700
From: kempf@Sun.COM
Dave's analysis has clarified things somewhat. Here's some additional
thoughts:
> MAKE-METHOD-FUNCTION proto-method generic-function qualifiers specializers
> lambda-exp &OPTIONAL macroexpand-environment
Yes, I agree that this is needed to handle CALL-NEXT-METHOD and other
metaclass dependent additions to the method function's lexical environment
(things like permutation tables are implementation specific details, and
therefore not part of the specification). I would have preferred to see
a more general function for constructing a function given a lexical
environment and a lambda expression, but, given the ambiguity in
Common Lisp about such topics, this will have to do.
> APPLY-METHOD method next-method-info &REST arguments
I don't think this generic function is really necessary,
since APPLY, being itself
implementation dependent, could be modified to do the right thing given
a method function. Some implementations of APPLY
already must differentiate based on whether the function object is a closure
or not, since in the former case, the lexical environment must be
modified to reflect the lexical environment of the closure, so the
additional case of a method function is probably nothing new.
However, it might be useful for metaobject programmers who want a hook
for a metaclass specific way of applying a method. In that case, I think
the NEXT-METHOD-INFO argument could be dropped, since the concept of
a next method is specific to STANDARD-METHOD. The method metaclass method
for this generic function would then implement any special processing
for changing control flow.
jak
∂11-Apr-88 1057 Common-Lisp-Object-System-mailer Re: method-lambda and apply-method-lambda
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 11 Apr 88 10:56:57 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 379803; Mon 11-Apr-88 13:56:17 EDT
Date: Mon, 11 Apr 88 13:56 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: method-lambda and apply-method-lambda
To: kempf@Sun.COM
cc: common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: <8804111558.AA05147@suntana.sun.com>
Message-ID: <19880411175624.6.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Mon, 11 Apr 88 08:58:35 -0700
From: kempf@Sun.COM
> APPLY-METHOD method next-method-info &REST arguments
I don't think this generic function is really necessary,
since APPLY, being itself
implementation dependent, could be modified to do the right thing given
a method function.
Jim, I think you must have missed the point. The problem isn't that what
APPLY does is implementation-dependent, but that the arguments to be passed
to APPLY are implementation-dependent. The most obvious case is the
next-method-info info; there is no way for APPLY to deduce this from the
other arguments, is there? If there is a way, I might change my mind on
suggesting a separate APPLY-METHOD primitive, but if there isn't a way,
we have to have that primitive so that the caller can supply the information.
Some implementations of APPLY
already must differentiate based on whether the function object is a closure
or not, since in the former case, the lexical environment must be
modified to reflect the lexical environment of the closure, so the
additional case of a method function is probably nothing new.
However, it might be useful for metaobject programmers who want a hook
for a metaclass specific way of applying a method. In that case, I think
the NEXT-METHOD-INFO argument could be dropped, since the concept of
a next method is specific to STANDARD-METHOD.
I disagree. I think CALL-NEXT-METHOD should be available to all classes
of methods that want it; I don't think it should be something magic for
standard-method.
The method metaclass method
for this generic function would then implement any special processing
for changing control flow.
I don't think I understand this last sentence; do you have a specific proposal?
∂11-Apr-88 1146 Common-Lisp-Object-System-mailer dependent update protocol
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 11 Apr 88 11:46:29 PDT
Received: from Semillon.ms by ArpaGateway.ms ; 11 APR 88 11:39:39 PDT
Date: Mon, 11 Apr 88 11:38 PDT
From: Gregor.pa@Xerox.COM
Subject: dependent update protocol
To: common-lisp-object-system@SAIL.STANFORD.EDU
Fcc: BD:>Gregor>mail>outgoing-mail-2.text
Message-ID: <880411113858.6.GREGOR@SPIFF.parc.xerox.com>
Line-fold: no
Moon has suggested that the dependents protocol stuff should not be part
of standard-object; rather it should be defined as a separate mixin
since that is what multiple inheritance is for after all. He also
mentioned some problems he had with the way the dependent protocol
worked. He didn't identify those problems, but we had some problems
with it ourselves which we have tried to address.
This message outlines a new dependents updating protcol. This protocol
is different from what we had before in several important ways:
- there is a separate mixin for the dependents stuff, that mixin
is used by standard-class to do dependents updating. Users can
use it in their code to particpate in that dependent updating
protocol.
- There is a mechanism for allowing the modified object to pass
information describing the modification to all the dependents.
This mechanism is designed to allow subclassing to work. That
is, a given class (say standard-class) may use this mechanism to
pass information to its dependents. Without specifying the
format of that information, a subclass of standard-class can
augment that information to pass extra information about how
it has been modified. Dependents of the subclass which expect to
see the augmented information will see it, dependents which do not
expect to see augmented information will see the original
information.
CLOS supports a general mechanism for registering dependents of objects,
and updating those objects on change. It does this through the medium
of a mixin class, updatable-object-mixin, that supports updating of
dependents. A dependent of an object O1 is any object that may need to
be updated when O1 changes. An object becomes a dependent only by
explicitly registering itself as one. The dependent registering
protocol allows redundant registering of dependents; this means that
code which wants an object to be registered as a dependent of an object
should always do so. It should never depend on the particular
implementation to do so since specific implementations may use the
dependent updating protocol in different ways.
Some examples of the use are:
1) A screen view of an object (perhaps a class) needs to update itself
when the object (class definition) changes. To do this it registers
itself as a dependent of that object, whenever the object changes it
will update all its dependents.
2) A subclass of a class wants to recompute its class precedence list
when the class changes its direct superclasses. The subclass
registers itself as a dependent of the class, whenever the class
changes, the subclass is updated and can recompute its class
precedence list.
3) Some set of objects needs to be updated when a class changes. This
can be handled in one of two ways, all the objects can be registered
as dependents, or a single object can be created which encapsulates
all the other objects. The single `large' object can be registered
as a dependent.
(defclass updatable-object-mixin () ())
This class supports two protocols, registration and updating of
dependents. The registration protocol is comprised of the generic
functions add-dependent, remove-dependent, and map-dependents. The
updating protocol is comprised of methods on reinitialize-instance, and
the generic functions before-reinitialization, after-reinitialization
and update-dependent.
The Registration Protocol
\Defmeth add-dependent ((object updatable-object-mixin) new-dependent)
adds new-dependent as a new dependent of object. Does nothing if
new-dependent is already a dependent of object.
\Defmeth remove-dependent ((object updatable-object-mixin) dependent)
removes dependent as one of the dependents of object. Does nothing
if dependent is not already one of the dependents of object.
\Defmeth map-dependents ((instance updatable-object-mixin) function args)
For all dependents of instance, applies function to instance,
the dependent and args.
The Updating Protocol
The updating protocol has two parts. The first part is an :around
method on reinitialize-instance which causes all the dependents of an
object to be updated whenever the object is reinitialized. This part of
the protocol also provides a mechanism which allows the object to pass
information to its dependents describing the change effected by
reinitializing the object. This mechanism is provided by having the
:around method on reinitialize-instance call the generic-function
before-reinitialization before the reinitialization, and the
generic-function after-reinitializing after the reinitialization. The
value returned by after-reinitialization is passed in the call to
update-dependent on each of the dependents.
[We are actively soliciting suggestions for better names for
before-reinitialization and after-reinitialization.]
(defmethod reinitialize-instance :around
((object updatable-object-mixin) &rest reinitargs)
(let ((before (apply #'before-reinitialization object reinitargs)))
(call-next-method)
(let ((update-args
(apply #'after-reinitialization object before reinitargs)))
(map-dependents object #'update-dependent object update-args))))
The updatable-object-mixin provides implementations of
before-reinitialization, after-reinitialization, and update-dependent.
(defmethod before-reinitialization ((object updateable-object) &rest ignore)
())
(defmethod after-reinitialization ((object updateable-object)
before-reinitialization
&rest ignore)
())
(defmethod update-dependent ((dependent updateable-object)
(object updateable-object)
after-reinitialization)
())
Example:
This example shows how this protocol might be used. In particular, it
demonstrates how the protocol can be used by a subclass to encapsulate
the information the superclas might pass. All use of this protocol
should be in this style. The standard methods on before-reinitialization,
after-reinitialization and update-dependent are there to support this.
Suppose that a specific kind of metaclass wants to propagate special
information when used as a submetaclass of itself. When ordinary
standard-class is used as a submetaclass, standard-class should see the
after-reinitialization information it was expecting to see.
(defclass my-class (standard-class) ())
(defmethod before-reinitialization ((c my-class) &rest reinitiargs)
(cons (<compute-the-magic-info>)
(call-next-method)))
(defmethod after-reinitialization ((c my-class) before &rest reinitargs)
(cons (<compute-the-magic-info>)
(apply #'call-next-method c (cdr before) reinitargs)))
(defmethod update-dependent ((dependent standard-class)
(object my-class)
after-reinitialization)
(call-next-method dependent object (cdr after-reinitialization)))
(defmethod update-dependent ((dependent my-class)
(object my-class)
after-reinitialization)
(<do something with the magic info>)
(call-next-method dependent object (cdr after-reinitialization)))
-------
∂11-Apr-88 1218 Common-Lisp-Object-System-mailer lattice of kernel classes
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 11 Apr 88 12:15:19 PDT
Received: from JUNCO.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 379903; Mon 11-Apr-88 15:15:09 EDT
Date: Mon, 11 Apr 88 15:14 EDT
From: Sonya E. Keene <skeene@STONY-BROOK.SCRC.Symbolics.COM>
Subject: lattice of kernel classes
To: common-lisp-object-system@SAIL.STANFORD.EDU
Message-ID: <19880411191450.4.SKEENE@JUNCO.SCRC.Symbolics.COM>
Three comments on this section of MOP:
1. In the diagram, there is a class named "standard-structure". I
think it is meant to be "structure-object"; which is what it is called
in the previous section.
2. The classes <structure-object> and <standard-object> have angle
brackets around them, which indicates that they are used primarily for
type determination, like <class>, <method>, and so on. I don't think
of those two classes in that way; I think of them as primarily being
there to support default behavior of instances of structure-class and
standard-class. So, I would recommend getting rid of the angle
brackets.
3. This section states that T is an instance of built-in class, but the
section "Instances of class, built-in-class, and structure-class" states
that an implementation can use standard-class for ANY class associated
with a Common Lisp type. This seems contradictory.
∂11-Apr-88 1250 Common-Lisp-Object-System-mailer dependent update protocol
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 11 Apr 88 12:50:16 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 379965; Mon 11-Apr-88 15:50:01 EDT
Date: Mon, 11 Apr 88 15:50 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: dependent update protocol
To: common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: <880411113858.6.GREGOR@SPIFF.parc.xerox.com>
Message-ID: <19880411195010.7.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Mon, 11 Apr 88 11:38 PDT
From: Gregor.pa@Xerox.COM
Moon has suggested that the dependents protocol stuff should not be part
of standard-object; rather it should be defined as a separate mixin
since that is what multiple inheritance is for after all. He also
mentioned some problems he had with the way the dependent protocol
worked. He didn't identify those problems, but we had some problems
with it ourselves which we have tried to address.
I believe those possible problems were with the next level up: the way
the updating of subclasses uses this protocol, not with this protocol itself.
I still haven't had time to figure out if those problems are real. However,
since your message didn't address that level at all, we can defer that.
This message outlines a new dependents updating protcol. This protocol
is different from what we had before in several important ways:
- there is a separate mixin for the dependents stuff, that mixin
is used by standard-class to do dependents updating. Users can
use it in their code to particpate in that dependent updating
protocol.
Good.
- There is a mechanism for allowing the modified object to pass
information describing the modification to all the dependents.
This mechanism is designed to allow subclassing to work. That
is, a given class (say standard-class) may use this mechanism to
pass information to its dependents.
Good.
Without specifying the
format of that information, a subclass of standard-class can
augment that information to pass extra information about how
it has been modified.
Actually your example shows that it's not really true that the format
of the information is unspecified. What is specified is that it is a list
with one element for each interested class, in most-specific-first order.
What is unspecified is the format of the list elements.
Dependents of the subclass which expect to
see the augmented information will see it, dependents which do not
expect to see augmented information will see the original
information.
This all seems good except for a couple of minor points:
\Defmeth map-dependents ((instance updatable-object-mixin) function args)
For all dependents of instance, applies function to instance,
the dependent and args.
It's usually better not to try to pass extra args through a mapping
function; instead the function being mapped can be a closure that knows
the extra args. This is more flexible, and is how all eight functions
in CLtL whose names start with "map" work. Thus I would make
map-dependents take only two arguments.
(defmethod reinitialize-instance :around
((object updatable-object-mixin) &rest reinitargs)
(let ((before (apply #'before-reinitialization object reinitargs)))
(call-next-method)
(let ((update-args
(apply #'after-reinitialization object before reinitargs)))
(map-dependents object #'update-dependent object update-args))))
I don't see how this can work if reinitialize-instance changes the set
of dependents. The map-dependents will map over the new dependents, and
any old dependents that were removed will never be updated. Maybe you
can say that remove-dependent, or by convention each caller of it, calls
update-dependent or a variant of it on the dependent being removed.
However, I suspect that is not flexible enough. I know some of our
analogues to this have to start by collecting all the dependents into a
table that is independent of the dependency structure. I don't have an
answer here; I think more thought is required.
This example shows how this protocol might be used. In particular, it
demonstrates how the protocol can be used by a subclass to encapsulate
the information the superclas might pass. All use of this protocol
should be in this style.
If that's true I would prefer to have the style (collecting lists of values
returned by each interested method, and taking them apart again) be enforced
by method combination, instead of leaving it up to each programmer to get
it right.
Also, since the style you propose depends on three methods for three different
generic functions to be kept in sync, and does something unpredictable without
necessarily signalling an error if one of the methods is left out, it doesn't
seem very robust. I would prefer to see either a more abstract data structure
than a list, so that leaving out a method (or forgetting to call cdr) for one
class would not damage the data seen by other class's methods, or else to use
one generic function instead of three, so that all the code for one class would
be in a single place and hence less likely to be out of sync. In the latter
case, this generic function would be called multiple times and one of its
arguments would indicate whether state was being collected or distributed.
My conclusion is that the registration protocol is okay but the updating
protocol needs more thought, although it certainly feels like it's on the
right track.
∂11-Apr-88 1335 Common-Lisp-Object-System-mailer Re: lattice of kernel classes
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 11 Apr 88 13:35:52 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 380027; Mon 11-Apr-88 16:35:39 EDT
Date: Mon, 11 Apr 88 16:35 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: lattice of kernel classes
To: common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: <880411-131548-12292@Xerox>
Message-ID: <19880411203548.9.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: 11 Apr 88 13:15 PDT
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
The reason for making T be a built-in-class is to ensure that
a) no instances of T can be made
b) No direct subclasses of T can be made (without significant effort)
I think we need some way to ensure this. Either we have to make T an exception
to the rule in Chapter 1, or put this information in more directly in Chpater 3.
What's wrong with (b)?
For (a), if you specifically want an error to be signalled if someone
makes an instance of the class named T, give it a make-instance method
that signals that error. I don't like errors that get detected by
fortunate coincidences, because that tends to result in error messages
that mere mortals can't understand.
∂11-Apr-88 1320 Common-Lisp-Object-System-mailer Re: lattice of kernel classes
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 11 Apr 88 13:19:57 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 11 APR 88 13:15:48 PDT
Date: 11 Apr 88 13:15 PDT
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Re: lattice of kernel classes
In-reply-to: Sonya E. Keene <skeene@STONY-BROOK.SCRC.Symbolics.COM>'s message of
Mon, 11 Apr 88 15:14 EDT
To: skeene@STONY-BROOK.SCRC.Symbolics.COM
cc: common-lisp-object-system@SAIL.STANFORD.EDU
Message-ID: <880411-131548-12292@Xerox>
1. In the diagram, there is a class named
"standard-structure". I think it is meant to be
"structure-object"; which is what it is called in the previous
section.
Right.
2. The classes <structure-object> and <standard-object> have
angle brackets around them, which indicates that they are used
primarily for type determination, like <class>, <method>, and so
on. I don't think of those two classes in that way; I think of
them as primarily being there to support default behavior of
instances of structure-class and standard-class. So, I would
recommend getting rid of the angle brackets.
I think that these classes serve both purposes. It is appropriate to test if an
object is structure using <structure-object>. So given the dual role of these
objects, do you think it better not to use <>, since that might indicate their
only purpose is for type checking, or is suffcient to amplify the statements
about their other roles in the text.
3. This section states that T is an instance of built-in
class, but the section "Instances of class, built-in-class, and
structure-class" states that an implementation can use
standard-class for ANY class associated with a Common Lisp type.
This seems contradictory.
The reason for making T be a built-in-class is to ensure that
a) no instances of T can be made
b) No direct subclasses of T can be made (without significant effort)
I think we need some way to ensure this. Either we have to make T an exception
to the rule in Chapter 1, or put this information in more directly in Chpater 3.
∂11-Apr-88 1344 Common-Lisp-Object-System-mailer method-lambda and apply-method-lambda
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 11 Apr 88 13:44:10 PDT
Received: from Semillon.ms by ArpaGateway.ms ; 11 APR 88 13:44:08 PDT
Date: Mon, 11 Apr 88 13:43 PDT
From: Gregor.pa@Xerox.COM
Subject: method-lambda and apply-method-lambda
To: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
cc: common-lisp-object-system@SAIL.STANFORD.EDU
Fcc: BD:>Gregor>mail>outgoing-mail-2.text
In-Reply-To: <19880408221409.1.MOON@EUPHRATES.SCRC.Symbolics.COM>
Message-ID: <880411134332.8.GREGOR@SPIFF.parc.xerox.com>
Line-fold: no
I have several minor questions with this proposal and one major one.
I will start with the major one since I think it addresses an important
characteristic of the proposal. The minor ones can be dealt with in a
later message.
The major problem I have is with making apply-method be a generic
function. It seems to me that doing this will prevent the
metacircularity from `bottoming out'. This is illustrated by the YES
answer to the following question:
- Are standard generic functions guaranteed to call apply-method?
Yes: But if apply-method is a generic function, how is it
itself implemented?
No: Then why bother having apply-method be a generic function,
what does it really buy me?
This is why the proposal include in the draft MOP had apply-method being
a function. It seemed to me that the code that called it was `below
the level of metacircularity' in the evaluator.
One way of seeing this is that the current design of the MOP has no
generic function invocations happening during the invocation of a
generic function. This simple rule prevents the kind of infinite
metacircularity problems that are coming up here.
-------
∂11-Apr-88 1410 Common-Lisp-Object-System-mailer method-lambda and apply-method-lambda
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 11 Apr 88 14:09:59 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 380099; Mon 11-Apr-88 17:09:44 EDT
Date: Mon, 11 Apr 88 17:09 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: method-lambda and apply-method-lambda
To: common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: <880411134332.8.GREGOR@SPIFF.parc.xerox.com>
Message-ID: <19880411210955.5.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Mon, 11 Apr 88 13:43 PDT
From: Gregor.pa@Xerox.COM
The major problem I have is with making apply-method be a generic
function. It seems to me that doing this will prevent the
metacircularity from `bottoming out'.
Patrick wanted the implementation-dependent calling sequence for method
functions to be under meta-object control, which is why he proposed
make-method-function to be generic. If make-method-function can select
from among several calling sequences, apply-method has to know which one
to use, which is the reason to make it generic too. We should see what
Patrick says, but it seems to me that either both of those functions
should be generic or neither should be.
I have no opinion of my own on whether the implementation-dependent
calling sequence for method functions should be under meta-object control.
But if apply-method is a generic function, how is it
itself implemented?
Clearly there is an infinite recursion if the standard method is not
special-cased. Since this is a meta-circular system, that's no
surprise, is it? Would this be the first place where a standard
method had to be special-cased? (That is not a rhetorical question;
I don't know the answer and I'm wondering.)
∂11-Apr-88 1441 Common-Lisp-Object-System-mailer Re: method-lambda and apply-method-lambda
Received: from Sun.COM by SAIL.Stanford.EDU with TCP; 11 Apr 88 14:41:20 PDT
Received: from snail.sun.com by Sun.COM (4.0/SMI-4.0)
id AA05758; Mon, 11 Apr 88 14:40:16 PDT
Received: from suntana.sun.com by snail.sun.com (4.0/SMI-3.2)
id AA23028; Mon, 11 Apr 88 14:39:42 PDT
Received: from localhost by suntana.sun.com (3.2/SMI-3.2)
id AA05721; Mon, 11 Apr 88 14:33:05 PDT
Message-Id: <8804112133.AA05721@suntana.sun.com>
To: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Cc: common-lisp-object-system@SAIL.STANFORD.EDU
Subject: Re: method-lambda and apply-method-lambda
In-Reply-To: Your message of Mon, 11 Apr 88 13:56:00 -0400.
<19880411175624.6.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Mon, 11 Apr 88 14:33:03 -0700
From: kempf@Sun.COM
> APPLY-METHOD method next-method-info &REST arguments
I don't think this generic function is really necessary,
since APPLY, being itself
implementation dependent, could be modified to do the right thing given
a method function.
Jim, I think you must have missed the point. The problem isn't that what
APPLY does is implementation-dependent, but that the arguments to be passed
to APPLY are implementation-dependent. The most obvious case is the
next-method-info info; there is no way for APPLY to deduce this from the
other arguments, is there? If there is a way, I might change my mind on
suggesting a separate APPLY-METHOD primitive, but if there isn't a way,
we have to have that primitive so that the caller can supply the information.
Why does the next method info have to be passed as arguments to APPLY or
an APPLY-like function in the first place? I thought the whole purpose of
MAKE-METHOD-FUNCTION was to return a function for which that information
has already been installed in the (some) environment, or maybe I'm missing
something. And that NEXT-METHOD-INFO gets it.
Some implementations of APPLY
already must differentiate based on whether the function object is a closure
or not, since in the former case, the lexical environment must be
modified to reflect the lexical environment of the closure, so the
additional case of a method function is probably nothing new.
However, it might be useful for metaobject programmers who want a hook
for a metaclass specific way of applying a method. In that case, I think
the NEXT-METHOD-INFO argument could be dropped, since the concept of
a next method is specific to STANDARD-METHOD.
I disagree. I think CALL-NEXT-METHOD should be available to all classes
of methods that want it; I don't think it should be something magic for
standard-method.
No, I didn't mean to imply that CALL-NEXT-METHOD would be magic. Look,
here's my vanillia implementation for MAKE-METHOD-FUNCTION for STANDARD-METHOD:
(defmethod make-method-function
((proto-method standard-method)
(generic-function standard-generic-function)
specializers
qualifiers
lambda-exp
&optional macroexpand-env
)
`(flet
( (call-next-method (&rest args)
(if (check-args args ',specializers)
(apply (get-next-method-function ',proto-method) args)
(apply #'no-applicable-method ',generic-function args)
)
)
)
,lambda-exp
)
)
The only "magic" here is GET-NEXT-METHOD-FUNCTION, and I can't think
of any other way to keep track of the next method function unless
the method knows about it's next method itself
(though there may be some ways to speed
up getting it, but this is a specification). Is there something
I'm missing here?
The method metaclass method
for this generic function would then implement any special processing
for changing control flow.
I don't think I understand this last sentence; do you have a specific proposal?
(defmethod apply-method ((method standard-method) &rest arguments)
(apply (method-function method) arguments)
)
Other metaclasses might want to control method application via their
method metaclass object, but the default would be not to.
I think I've got a different (and perhaps wrong?) model about what's
going on. My model is that MAKE-METHOD-FUNCTION constructs a function
in which the metaclass dependent specialized control flow primitives
(e.g. CALL-NEXT-METHOD) are part of the lexical environment
seen by the user code (LAMBDA-EXP). Any other system dependent
information needed to influence control flow (e.g. permutation tables)
would also need to be included, but naming access controlled so only system
code sees it. NEXT-METHOD-INFO, or whatever the accessor function
is named, is able to get at that information in some implementation
dependent way. Thus, the method function should be invokable via
APPLY, with APPLY-METHOD more of a utility should a metaobject user
happen to have a method and not want to retieve the function.
want to use it. No hidden arguments to APPLY needed.
Anyway, let me know if this is making sense, or if it's only a result
of allergic reaction to springtime pollen.
jak
∂11-Apr-88 1624 Common-Lisp-Object-System-mailer method-lambda and apply-method-lambda
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 11 Apr 88 16:23:59 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 11 APR 88 16:17:46 PDT
Date: Mon, 11 Apr 88 16:17 PDT
From: Gregor.pa@Xerox.COM
Subject: method-lambda and apply-method-lambda
To: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
cc: common-lisp-object-system@SAIL.STANFORD.EDU
Fcc: BD:>Gregor>mail>outgoing-mail-2.text
In-Reply-To: <19880411210955.5.MOON@EUPHRATES.SCRC.Symbolics.COM>
Message-ID: <880411161708.3.GREGOR@SPIFF.parc.xerox.com>
Line-fold: no
Date: Mon, 11 Apr 88 17:09 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Patrick wanted the implementation-dependent calling sequence for method
functions to be under meta-object control, which is why he proposed
make-method-function to be generic.
I should have noticed this before, unfortunately it didn't jump out at
me till over this weekend though. In thinking about this even further,
I have concluded that the basic idea of having make-method-function and
apply-method be generic functions is flawed. This message tries to
explore the reasoning behind this conclusion.
The basic conclusion is that the abstraction which Patrick and David's
proposal (the proposal) was trying to provide is inappropriate. It is
trying to place an abstraction barrier between the method lookup
mechanism and the method invocation mechanism, and it turns out it isn't
a good idea to put an abstraction barrier there.
Lets start by looking carefully at the abstraction the proposal is
trying to provide. It is trying to prevent the generic function's
method lookup mechanism from having to know the calling sequence of the
actual methods. We might have thought that it was trying to protect the
actual generic function from having to know the calling sequence of the
method, but the fact that make-method-function takes the generic
function as its first argument shows that that isn't true.
Now we have to decide whether it makes sense for the actual method
calling sequence to be isolated from the generic function's method
lookup mechanism. I will argue that it doesn't.
The basic reason is that the method lookup mechanism and the method
calling sequence `want' to be intimately connected. For example, the
method lookup mechanism is supremely qualified to be looking up the
next-method-info; but in the abstraction presented by the proposal, the
actual method calling sequence must do that lookup itself. It isn't
clear how one could implement a high performance method lookup and
invocation mechanism which also had to pass special information using
this protocol.
Now lets look at the case where one wants to have a different kind of
method on a generic function, where that different kind of method has a
different calling sequence. In the proposal, if the different kind of
method has a different calling sequence, the class of the generic
function will have to be different (make-method-function takes the
generic function as its only specializable argument).
Using the mop as written up (sort of) and implemented in PCL, the
generic function would also have to have a special class, and the method
lookup and invocation code would both be specialized by specializing the
single generic function compute-discriminator-code. As mentioned two
paragraphs above, this is likely to have higher performance as well.
I think that the way to think about this is to acknowledge that generic
functions must understand the calling needs of their methods. This
seems quite reasonable since they must already understand when to call
their methods. In order to have methods which have special calling
needs, one must have a special class of generic function which
understands their calling needs. Understanding their calling needs can
be thought of as part of the contract which the generic function entered
into when it agreed to have the method as one of its methods.
It could be argued that my argument is based on the existing arguments
to make-method-function and apply-method; that by changing the proposal
so that those generic functions accepted only the method as arguments,
it would be possible to specialize only the method to have a special
calling sequence. This may be true, but the real point of my argument
is that this isn't a good architecture because it separates the method
lookup mechanism from the method invocation mechanism in an unatural
way. In addition, the proposal has some other problems which I began to
surface in my last message.
-------
∂11-Apr-88 1604 Common-Lisp-Object-System-mailer Re: method-lambda and apply-method-lambda
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 11 Apr 88 16:04:19 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 380246; Mon 11-Apr-88 19:03:59 EDT
Date: Mon, 11 Apr 88 19:04 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: method-lambda and apply-method-lambda
To: common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: <8804112133.AA05721@suntana.sun.com>
Message-ID: <19880411230405.9.MOON@EUPHRATES.SCRC.Symbolics.COM>
[Sorry about the length of this message. I couldn't find anything
to delete without losing the sense of the conversation.]
Date: Mon, 11 Apr 88 14:33:03 -0700
From: kempf@Sun.COM
> APPLY-METHOD method next-method-info &REST arguments
I don't think this generic function is really necessary,
since APPLY, being itself
implementation dependent, could be modified to do the right thing given
a method function.
Jim, I think you must have missed the point. The problem isn't that what
APPLY does is implementation-dependent, but that the arguments to be passed
to APPLY are implementation-dependent. The most obvious case is the
next-method-info info; there is no way for APPLY to deduce this from the
other arguments, is there? If there is a way, I might change my mind on
suggesting a separate APPLY-METHOD primitive, but if there isn't a way,
we have to have that primitive so that the caller can supply the information.
Why does the next method info have to be passed as arguments to APPLY or
an APPLY-like function in the first place? I thought the whole purpose of
MAKE-METHOD-FUNCTION was to return a function for which that information
has already been installed in the (some) environment, or maybe I'm missing
something. And that NEXT-METHOD-INFO gets it.
MAKE-METHOD-FUNCTION can only depend on static information, which is the
same every time the method is called. That's because MAKE-METHOD-FUNCTION
is called once and the result is stored as the method-function
conceptual-slot of the method meta-object. MAKE-METHOD-FUNCTION isn't
called every time the generic function is called, as I understand it. The
NEXT-METHOD-INFO is dynamic information since it depends on what other
methods are also applicable, which can vary from one call to the next.
Some implementations of APPLY
already must differentiate based on whether the function object is a closure
or not, since in the former case, the lexical environment must be
modified to reflect the lexical environment of the closure, so the
additional case of a method function is probably nothing new.
However, it might be useful for metaobject programmers who want a hook
for a metaclass specific way of applying a method. In that case, I think
the NEXT-METHOD-INFO argument could be dropped, since the concept of
a next method is specific to STANDARD-METHOD.
I disagree. I think CALL-NEXT-METHOD should be available to all classes
of methods that want it; I don't think it should be something magic for
standard-method.
No, I didn't mean to imply that CALL-NEXT-METHOD would be magic. Look,
here's my vanillia implementation for MAKE-METHOD-FUNCTION for STANDARD-METHOD:
(defmethod make-method-function
((proto-method standard-method)
(generic-function standard-generic-function)
specializers
qualifiers
lambda-exp
&optional macroexpand-env
)
`(flet
( (call-next-method (&rest args)
(if (check-args args ',specializers)
(apply (get-next-method-function ',proto-method) args)
(apply #'no-applicable-method ',generic-function args)
)
)
)
,lambda-exp
)
)
The only "magic" here is GET-NEXT-METHOD-FUNCTION, and I can't think
of any other way to keep track of the next method function unless
the method knows about it's next method itself
(though there may be some ways to speed
up getting it, but this is a specification). Is there something
I'm missing here?
Maybe there's something I'm missing, because I can't imagine what the
implementation of GET-NEXT-METHOD-FUNCTION could possibly be. I just
don't see from where it can figure out what method to call. That
depends on the current method's position in the precedence-ordered
list of applicable methods with relevant qualifiers, and I don't see
how GET-NEXT-METHOD-FUNCTION can find either of those quantities.
That's why I think there has to be a "next-method-info" object that
gets passed around as an extra argument. One implementation of
call-next-method would be to funcall the car of next-method-info,
passing the cdr of next-method-info to it. CLOS shouldn't mandate
that it be a list, though.
The method metaclass method
for this generic function would then implement any special processing
for changing control flow.
I don't think I understand this last sentence; do you have a specific proposal?
(defmethod apply-method ((method standard-method) &rest arguments)
(apply (method-function method) arguments)
)
Other metaclasses might want to control method application via their
method metaclass object, but the default would be not to.
I still don't understand, but that's probably irrelevant for now.
I think I've got a different (and perhaps wrong?) model about what's
going on. My model is that MAKE-METHOD-FUNCTION constructs a function
in which the metaclass dependent specialized control flow primitives
(e.g. CALL-NEXT-METHOD) are part of the lexical environment
seen by the user code (LAMBDA-EXP).
That's my model too.
Any other system dependent
information needed to influence control flow (e.g. permutation tables)
would also need to be included, but naming access controlled so only system
code sees it.
Agreed (except permutation tables may be only for data access, not for
control flow; that in fact depends on the implementation, and we have
tried it both ways. Right now we do some control flow there and other
control flow elsewhere.)
NEXT-METHOD-INFO, or whatever the accessor function
is named, is able to get at that information in some implementation
dependent way.
Agreed.
Thus, the method function should be invokable via
APPLY, with APPLY-METHOD more of a utility should a metaobject user
happen to have a method and not want to retieve the function.
want to use it. No hidden arguments to APPLY needed.
Non-sequitur. The fact that CALL-NEXT-METHOD is part of the lexical
environment does not mean that the body of CALL-NEXT-METHOD contains no
free variables. Indeed, since CALL-NEXT-METHOD in a given method does not
do the same thing every time it is called, it must depend in some way on a
free variable or the equivalent. A lot of this discussion is about how to
model that free variable and how abstract to be about it. For instance, if
we wanted to totally constrain implementation techniques, we could do
something like setf-functions and say "every method-function takes one
extra argument, before the arguments visible in defmethod, and the value of
this argument is a list of method functions. The parameter bound to this
argument is named CLOS-SYSTEM-INTERNALS::NEXT-METHOD-LIST and
CALL-NEXT-METHOD works by funcalling its car, passing its cdr as the first
argument." I don't think being so concrete would be wise, and I don't
think it's necessary either. We shouldn't say what form that information
is represented in (maybe it's an array rather than a list, maybe the
entries are method meta-objects, rather than method-functions, or maybe the
entries are machine program counter values), and we shouldn't say through
what path the information is delivered (maybe it's passed in machine
register A5, rather than being passed as a Lisp argument; maybe it's
stashed in a special variable). But we do have to recognize that the
information exists and if we want to be able to do things like tracing
methods we have to provide a way to transmit the information from one
function to another.
Okay, where does this mysterious "information" come from in the first place?
My model is that the generic function dispatch produces not only a method
function to be called, but also this extra information to be passed to it.
Thus it's a function of the argument classes (or identities) that gets
precomputed and stored in the method lookup tables. Just as we don't
dictate that any particular form of method lookup tables be used, even
though every implementation has to have them in some form, we shouldn't
dictate any particular form of this information, nor should we dictate
whether it is precomputed or calculated on demand when call-next-method
is done (if you were assuming we always calculate it on demand, you have
to think about what information is required to calculate it).
∂11-Apr-88 1739 Common-Lisp-Object-System-mailer Reinitialization
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 11 Apr 88 17:35:07 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 380302; Mon 11-Apr-88 20:34:57 EDT
Date: Mon, 11 Apr 88 20:35 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Reinitialization
To: Common-Lisp-Object-System@SAIL.STANFORD.EDU
In-Reply-To: <19880323170326.4.MOON@EUPHRATES.SCRC.Symbolics.COM>,
<880405173737.1.GREGOR@SPIFF.parc.xerox.com>,
The message of 6 Apr 88 13:43 EDT from Dick Gabriel <RPG@SAIL.Stanford.EDU>,
<880406125216.9.GREGOR@SPIFF.parc.xerox.com>,
<880406194011.3.GREGOR@SPIFF.parc.xerox.com>,
<880407-100805-6877@Xerox>,
<880407103428.1.GREGOR@SPIFF.parc.xerox.com>,
<8804071913.AA01613@suntana.sun.com>,
The message of 7 Apr 88 17:51 EDT from Dick Gabriel <RPG@SAIL.Stanford.EDU>,
<880407191422.6.GREGOR@SPIFF.parc.xerox.com>,
<880407191538.7.GREGOR@SPIFF.parc.xerox.com>,
<8804081541.AA02698@suntana.sun.com>,
<8804081903.AA03057@suntana.sun.com>,
<880408-153713-9540@Xerox>
Message-ID: <19880412003504.0.MOON@EUPHRATES.SCRC.Symbolics.COM>
I've been reading this mail, but I haven't said anything because it's
all pretty confusing and I've been thinking. So far I've identified
seven different relevant issues that we've been discussing here. I'll
list them and offer my own opinion on each one. I almost feel I shouldn't
send this, as it's still pretty confusing. However, since it's been
a week I'm probably not doing anyone any good by keeping this to myself.
When I say "the four updating functions", I mean initialize-instance,
reinitialize-instance, class-changed, and update-instance-structure.
(1) How much should be shared among the four updating functions? My
original complaint was that too much was shared, when reinitialize-instance
simply called initialize-instance. Then we noticed that the other two
updating functions don't share anything, but could. I agree that all
four should share something, but not everything (i.e. none of the four
updating functions should call one of the others). This issue doesn't
seem to be controversial. However, after you see what's below maybe
you'll decide that trying to share anything is hopeless and we'd be
better off duplicating some code rather than complexifying the language.
(2) What should be shared among the four updating functions? There are
actually three different things:
(a) the code to fill slots from initialization arguments
(b) the code to fill slots from values of initialization forms
(c) user-defined methods
So far the discussion does not seem to have recognized that we are talking
about three distinct things that could be shared. The thing we are talking
about sharing is -not- simply the primary method for initialize-instance.
Now, (a) only makes sense for initialize and reinitialize, since the other
two don't have initialization arguments. (b) doesn't make sense for
reinitialize in my opinion, and should only be done for newly added slots
for class-changed and update-instance-structure, in my opinion (see issue
4). (c) definitely makes sense for all four, except that only initialize
and reinitialize would pass initialization arguments to the user-defined
methods. By the way, (c) is what Barry Margolin brought up at X3J13,
so that's committee input to which we must respond.
The most straightforward thing to do here would be to provide -three-
shared functions:
(a) initialize-slots-from-initargs instance &rest initialization-arguments
(b) initialize-slots-from-initforms instance list-of-slots-to-consider
(c) normalize-instance instance &rest initialization-arguments
[Never mind the names, that's issue 7]
The primary method for initialize-instance would call all three.
The primary method for reinitialize-instance would call (a) and (c).
The primary methods for class-changed and update-instance-structure would call
(b) and (c), but the second argument to (b) would be only the added local slots
and (c) would be called with only one argument.
Maybe we don't need quite this much mechanism. For instance, (a) and (c)
could be combined if the name of (a) didn't contain the word "slots",
except that the primary method for initialize-instance ought to call (b)
between (a) and (c). Another question is whether (a) and (b) should be
generic, and if so whether they should dispatch on the instance or on
the class. (c) obviously is generic and dispatches on the instance.
If (a) and (b) don't have to be generic, a radical proposal that I think
should be considered would be to move them back into the implementation
dependent part of the system so that they need not be named in the standard.
I don't have a proposal to make on issue (2) at this time. I hope I've
clarified what we're talking about, though.
(3) We've discussed several clever/kludgey ways to tweak the shared code so
it behaves differently for each of the four updating functions. I don't
think any of them should be adopted. I only suggested this by analogy with
slot-missing and because of the excessive sharing between initialize and
reinitialize. If I had thought it out before sending my message I would
not have suggested it. Once things are modularized correctly, I don't
think this extra hair would be used and I don't think we want to put it
into the language.
(4) A subtle semantic change to class-changed and update-instance-structure
has been proposed, specifically that unbound slots that are not new should
be filled from their initforms instead of being left unbound. I'm opposed
to this change, for two reasons. One is that I'm opposed to making any
changes in the first two chapters unless there is a good reason; I want
that part of the CLOS spec to be over and done with. The second is that I
think an unbound slot should be treated the same as a slot with a value in
it, except when you read it. By that rule, it's as wrong for class-changed
to bash unbound slots as it would be for it to bash slots with values in
them. As far as I know the only reason for proposing this change was that
it appeared to simplify the sharing issue. I don't think that would be a
good enough reason for a semantic change even if, after we understand the
sharing issue, it turns out to be true.
(5) Do we really need four different updating functions? I think the answer
is yes, because user-defined methods could quite plausibly do different things
for each one. The only case I'm not sure of is whether class-changed and
update-instance-structure really need to be distinguished by user-defined
methods. Maybe they are only distinct because they take different arguments
now.
(6) Why do the four updating functions have such inconsistent interfaces?
It makes sense for two of them to take initialization arguments and the
other two to take before & after instance states, so the real issue is why
don't class-changed and update-instance-structure take similar arguments?
I believe that is only an artifact of the way CLOS evolved; when we
abandoned the attempt to maintain a complete model of class redefinition
history, we also stopped passing a copy of the instance with its old
structure to update-instance-structure. That was because we didn't have
any class to use for that instance. However, just as class-changed gets a
temporary instance with potentially dynamic extent,
update-instance-structure could get a temporary instance of a temporary
class. That would be good, because the information about what slots were
added and removed could be accessed through the normal Chapter 3 class
examination functions, instead of through special kludgey property lists,
and the values of slots could be accessed the normal way.
Although I am reluctant to change Chapters 1 and 2, I think it would be
justified to make update-instance-structure take two instances as
arguments, the same as class-changed. We should also change the name of
update-instance-structure to make it more analogous (e.g. class-redefined).
It would probably also be okay to get rid of the distinction between
class-changed and update-instance-structure and just have one generic
function for both, although I haven't thought out the implications of that.
We should be real careful here, as we did think all this stuff out
moderately carefully and we may all have forgotten the reasons by now.
(7) What are good names for these five functions, the four updating ones
and the shared one? I spent some time thinking about this without
satisfactory results. Possible words for the shared operation could be
prepare, normalize, renew, reconcile, settle, adjust, adapt, setup, or
tidy. None of those really works. Another idea would be to call the
shared operation initialize-instance and rename the function that
make-instance calls to initialize-new-instance or instance-made. There is
also this incoherence between class-changed ("something happened") and just
about all the other names ("do something"). I think we're still waiting
for a good idea here, and maybe we should first settle the modularity
before we pick the names. The problem is that the existing names color
one's ideas about what the modularity should be. We're also rapidly
approaching the day when we shouldn't change names because of the
programmer retraining problem.
∂11-Apr-88 1755 Common-Lisp-Object-System-mailer method-lambda and apply-method-lambda
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 11 Apr 88 17:55:47 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 380320; Mon 11-Apr-88 20:55:19 EDT
Date: Mon, 11 Apr 88 20:55 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: method-lambda and apply-method-lambda
To: Gregor.pa@Xerox.COM
cc: common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: <880411161708.3.GREGOR@SPIFF.parc.xerox.com>
Message-ID: <19880412005526.4.MOON@EUPHRATES.SCRC.Symbolics.COM>
Line-fold: No
There's something missing from your message. Isn't the only reason
make-method-function and apply-method were proposed (by you originally,
Gregor) to allow users to interject code between the method lookup and
the method invocation, for instance when tracing? Otherwise there would
be no need to standardize these little pieces of the implementation of
generic functions when we don't standardize all the rest of it.
So I think the abstraction barrier isn't between method lookup and
method invocation, but rather between those two mechanisms on the one
hand and user-written code on the other. But this only says why these
two functions should exist, not whether they should be generic or not.
I agree that the method lookup mechanism and the method invocation
mechanism need to understand each other in detail. What I don't
understand is how that has any bearing on whether or not these two
functions should be generic, i.e. whether or not there should exist
more than one method invocation mechanism. I guess I don't understand
PCL's compute-discriminator-code generic function, since I don't
understand how specializing that could affect what parameters the
compiler makes a method-function accept.
In conclusion, while I agree with all of your message that I understood,
it doesn't seem to me to have any bearing on the issue it was supposed
to be about. Obviously I missed something big that you thought was there.
∂12-Apr-88 0859 Common-Lisp-Object-System-mailer two questions about standard-class
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 12 Apr 88 08:58:50 PDT
Received: from JUNCO.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 380543; Tue 12-Apr-88 11:58:34 EDT
Date: Tue, 12 Apr 88 11:58 EDT
From: Sonya E. Keene <skeene@STONY-BROOK.SCRC.Symbolics.COM>
Subject: two questions about standard-class
To: common-lisp-object-system@SAIL.STANFORD.EDU
Message-ID: <19880412155813.0.SKEENE@JUNCO.SCRC.Symbolics.COM>
A class is considered initialized if its direct superclasses are known.
I don't understand this; how can a class be defined without stating what
its direct superclasses are?
I was also confused about class-default-direct-superclasses. I
understand what it is supposed to do (the method for standard-class
ensures that standard-object is included in the CPL). The
documentation (page 3-14 on my draft) says if there are any supplied
superclasses, this method returns the list of supplied superclasses and
doesn't add standard-object to that list. If there are no supplied
superclasses, this method returns a list containing standard object.
The goal of this approach seems to be not to require standard-object to
be a direct superclass of each class (otherwise the method would always
add standard-object to the list). The assumption seems to be that if
there is a supplied superclass, it already has standard-object in its
CPL. Does this really work? What if you define a class and specify
T to be the only direct superclass?
[Whatever the answer to the question, if I stated the goal of the
approach correctly, it should probably be written down in the
documentation.]
∂12-Apr-88 1027 Common-Lisp-Object-System-mailer method-lambda and apply-method-lambda
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 12 Apr 88 10:27:34 PDT
Received: from Semillon.ms by ArpaGateway.ms ; 12 APR 88 10:23:05 PDT
Date: Tue, 12 Apr 88 10:21 PDT
From: Gregor.pa@Xerox.COM
Subject: method-lambda and apply-method-lambda
To: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
cc: common-lisp-object-system@SAIL.STANFORD.EDU
Fcc: BD:>Gregor>mail>outgoing-mail-2.text
In-Reply-To: <19880412005526.4.MOON@EUPHRATES.SCRC.Symbolics.COM>
Message-ID: <880412102105.6.GREGOR@SPIFF.parc.xerox.com>
Line-fold: no
Date: Mon, 11 Apr 88 20:55 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
There's something missing from your message. Isn't the only reason
make-method-function and apply-method were proposed (by you originally,
Gregor) to allow users to interject code between the method lookup and
the method invocation, for instance when tracing? Otherwise there would
be no need to standardize these little pieces of the implementation of
generic functions when we don't standardize all the rest of it.
I believe that I originally proposed method-lambda and apply-method as
unspecializable interfaces to the standard kind of method. I still (or
once again) believe that all we need is some sort of unspecializable
interface to the implementation specific calling sequence for standard
methods. This will allow two things:
1) users can generate method functions which can be used by the
implementation's own method lookup and invocation code.
(method-lambda or make-method-function)
2) users can call the implementations own method functions if they
want to (usually for some sort of debugging or tracing purposes).
(apply-method-function)
While I still like method lambda (for the reasons I stated in a previous
message), I am willing to accept your argument that:
Right. I agree that the two properties Gregor proposes sound important,
but I believe that it is impossible to achieve those properties. I think
that the attempt to achieve those properties is why we've been having
trouble converging here. Giving up those properties will make the problem
much easier, and I don't think it means giving up anything that matters.
and am willing to accept your suggestion that the criterion we should
shoot for are:
I think the -only- assertions guaranteed about the value returned by
MAKE-METHOD-FUNCTION should be:
- COMPILE works on it
- the FUNCTION special form works on it
- it and the result of compiling it are members of the type FUNCTION
- APPLY-METHOD works on it and on the result of compiling it
- it and the result of compiling it can be used as the :method-function
when creating or reinitializing a method meta-object
Which means I am proposing that have make-standard-method-function as
an unspecializable function whose result has the above properties and
apply-standard-method-function as an unspecializable function which can
be used to apply them.
I also think the next methods argument to apply-standard-method-function
should be a list since I don't see any real advantage to making an
abstraction for it. Remember that in this scheme, it is clear that
apply-standard-method-function is not really the mechanism used by
standard method lookup. Rather it is a hook which the standard lookup
mechanism provides for unpriveledged callers of the method functions.
So I think the abstraction barrier isn't between method lookup and
method invocation, but rather between those two mechanisms on the one
hand and user-written code on the other. But this only says why these
two functions should exist, not whether they should be generic or
not.
Right.
I agree that the method lookup mechanism and the method invocation
mechanism need to understand each other in detail. What I don't
understand is how that has any bearing on whether or not these two
functions should be generic, i.e. whether or not there should exist
more than one method invocation mechanism. I guess I don't understand
PCL's compute-discriminator-code generic function, since I don't
understand how specializing that could affect what parameters the
compiler makes a method-function accept.
The idea is not that specializing compute-discriminator-code can "affect
what parameters the compiler makes a method-function accept". Rather,
the idea is that for a given method on compute-discriminator-code there
is a certain kind of method function (and corresponding calling
sequence) which is appropriate. A given class of generic function
states (by having an appropriate method on add-method) whether or not it
is willing to contract with the calling sequence of a given class of
method's functions. If there is such a method on add-method, it is a
declaration that the compute-discriminator-code method for that class
of generic function can handle that class of method.
In conclusion, while I agree with all of your message that I understood,
it doesn't seem to me to have any bearing on the issue it was supposed
to be about. Obviously I missed something big that you thought was
there.
We have to find some way to converge on this soon. My basic point is
that the genericity should be at the level of add-method and
compute-discriminator-code and that at the level of making method
functions and calling method functions the code should not be generic.
I am afraid I am just restating myself, but perhaps I have clarified
some part of what I was trying to say?
-------
∂12-Apr-88 1502 Common-Lisp-Object-System-mailer Re: Reinitialization
Received: from Sun.COM by SAIL.Stanford.EDU with TCP; 12 Apr 88 15:02:25 PDT
Received: from snail.sun.com by Sun.COM (4.0/SMI-4.0)
id AA21618; Tue, 12 Apr 88 15:01:21 PDT
Received: from suntana.sun.com by snail.sun.com (4.0/SMI-3.2)
id AA21712; Tue, 12 Apr 88 14:59:48 PDT
Received: from localhost by suntana.sun.com (3.2/SMI-3.2)
id AA07085; Tue, 12 Apr 88 14:52:40 PDT
Message-Id: <8804122152.AA07085@suntana.sun.com>
To: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Cc: Common-Lisp-Object-System@SAIL.STANFORD.EDU
Subject: Re: Reinitialization
In-Reply-To: Your message of Mon, 11 Apr 88 20:35:00 -0400.
<19880412003504.0.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Tue, 12 Apr 88 14:52:35 -0700
From: kempf@Sun.COM
Couple responses/questions
> (a) initialize-slots-from-initargs instance &rest initialization-arguments
> (b) initialize-slots-from-initforms instance list-of-slots-to-consider
> (c) normalize-instance instance &rest initialization-arguments
I like this seperation, except I'm not sure what you have in mind
for normalize-instance?
>Another question is whether (a) and (b) should be
>generic, and if so whether they should dispatch on the instance or on
>the class.
Yes, I think they should. Example: a persistance metaclass which wanted
to initialize slots in a database. Certainly, this could be done in
bulk by specializing initialize, but the programmer might also want
it done in the other cases as well.
>(4) A subtle semantic change to class-changed and update-instance-structure
>has been proposed, specifically that unbound slots that are not new should
>be filled from their initforms instead of being left unbound. I'm opposed
I don't recall having seen the change, but I agree with your arguments
against it.
>One is that I'm opposed to making any
>changes in the first two chapters unless there is a good reason; I want
>that part of the CLOS spec to be over and done with.
This is also the best reason for keeping the four updating functions.
>(6) Why do the four updating functions have such inconsistent interfaces?
>It makes sense for two of them to take initialization arguments and the
I agree with your proposed changes, but, again, this would involve
changes in Chapters 1 & 2.
jak
∂12-Apr-88 1520 Common-Lisp-Object-System-mailer Re: Reinitialization
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 12 Apr 88 15:20:24 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 380883; Tue 12-Apr-88 18:20:05 EDT
Date: Tue, 12 Apr 88 18:20 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: Reinitialization
To: Common-Lisp-Object-System@SAIL.STANFORD.EDU
In-Reply-To: <8804122152.AA07085@suntana.sun.com>
Message-ID: <19880412222014.9.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Tue, 12 Apr 88 14:52:35 -0700
From: kempf@Sun.COM
> (a) initialize-slots-from-initargs instance &rest initialization-arguments
> (b) initialize-slots-from-initforms instance list-of-slots-to-consider
> (c) normalize-instance instance &rest initialization-arguments
I like this seperation, except I'm not sure what you have in mind
for normalize-instance?
This a-b-c was parallel with the other one, so normalize-instance is where
the user-defined methods for the shared part of initialization go. The
default method would be a no-op.
∂12-Apr-88 1748 Common-Lisp-Object-System-mailer Re: Reinitialization
Received: from WILMA.BBN.COM ([128.89.1.216]) by SAIL.Stanford.EDU with TCP; 12 Apr 88 17:48:37 PDT
To: "David A. Moon" <Moon@stony-brook.scrc.symbolics.com>
cc: Common-Lisp-Object-System@sail.stanford.edu
Subject: Re: Reinitialization
In-reply-to: Your message of Tue, 12 Apr 88 18:20:00 -0400.
<19880412222014.9.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Tue, 12 Apr 88 20:42:08 -0400
From: kanderso@WILMA.BBN.COM
Please correct me if i'm wrong, i've been trying to trying to follow
this discussion from the outside. Are you talking about a
reinitialization protocal in general, or about reinitialization of
classes or methods when they change? I can think of a lot of
different initialization behavior besides those two: after allocation
for a resource (i was something else before, now i'm expected to
behave like this), when a simulation object is reset to some initial
state, etc. Maybe what they have is common is to abstract [vague], so
there is very little behavior of value to share, otherwise we would
have agreed on something by now. So my question is, should we
consider each of these types of initialization as separate? Perhaps,
after we fill them out, we'll see the similarities.
k
∂12-Apr-88 1835 Common-Lisp-Object-System-mailer Re: Reinitialization
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 12 Apr 88 18:35:47 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 381003; Tue 12-Apr-88 21:33:57 EDT
Date: Tue, 12 Apr 88 21:34 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: Reinitialization
To: kanderso@WILMA.BBN.COM
cc: Common-Lisp-Object-System@SAIL.STANFORD.EDU
In-Reply-To: The message of 12 Apr 88 20:42 EDT from kanderso@WILMA.BBN.COM
Message-ID: <19880413013405.6.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Tue, 12 Apr 88 20:42:08 -0400
From: kanderso@WILMA.BBN.COM
Please correct me if i'm wrong, i've been trying to trying to follow
this discussion from the outside. Are you talking about a
reinitialization protocal in general, or about reinitialization of
classes or methods when they change?
Maybe I should let Gregor answer, since it was his idea.
Both. The immediate goal is to codify how classes and generic functions
change (not methods; for some reason method objects are immutable
instead of being redefinable like the other two major kinds of meta
objects.) However, the idea is to codify this in terms of a generalized
reinitialization mechanism that can also be used for other things, by users.
∂13-Apr-88 0809 Common-Lisp-Object-System-mailer Announcing New Journal on Object-Oriented Programming
Received: from Sun.COM by SAIL.Stanford.EDU with TCP; 13 Apr 88 08:09:21 PDT
Received: from snail.sun.com by Sun.COM (4.0/SMI-4.0)
id AA01194; Wed, 13 Apr 88 08:08:41 PDT
Received: from suntana.sun.com by snail.sun.com (4.0/SMI-3.2)
id AA05564; Wed, 13 Apr 88 08:08:06 PDT
Received: from localhost by suntana.sun.com (3.2/SMI-3.2)
id AA07797; Wed, 13 Apr 88 08:01:33 PDT
Message-Id: <8804131501.AA07797@suntana.sun.com>
To: common-lisp-object-system@sail.stanford.edu, commonloops.pa@xerox.com
Subject: Announcing New Journal on Object-Oriented Programming
Date: Wed, 13 Apr 88 08:01:31 -0700
From: kempf@Sun.COM
For those of you who have not yet heard, there is a new journal dedicated
to object-oriented programming. The name is the Journal of Object-Oriented
Programming and the address is:
Journal of Object-Oriented Programming
P.O. Box 66338
Woodland Park, CO
80866
303-687-2517
The editor in chief is Dr. Richard Wiener from U. Colorado at Colorado
Springs.
People who have interesting applications using the PCL implementation
of CLOS, New Flavors, or other Lisp object-oriented languages are
encouraged to send in manuscripts. You can also send them to me if
you want, since I'm the review board representative for Lisp.
The first issue is due out in May, and it is targeted for 6 issues a
year, in case you care to subscribe.
Editorial Comment:
I think it is extremely important that people in the object-oriented
programming community using Lisp based object-oriented languages become
more visible. Many of the more technically innovative uses of object-oriented
programming are coming from Lisp users, but the object-oriented community
at large often ignores Lisp object-oriented programmers.
jak
∂13-Apr-88 0848 Common-Lisp-Object-System-mailer Re: method-lambda and apply-method-lambda
Received: from ti.com by SAIL.Stanford.EDU with TCP; 13 Apr 88 08:48:06 PDT
Received: by ti.com id AA29239; Wed, 13 Apr 88 10:45:12 CDT
Received: from Jenner by tilde id AA03273; Wed, 13 Apr 88 10:23:42 CDT
Message-Id: <2785937331-3382088@Jenner>
Date: Wed, 13 Apr 88 10:28:51 CDT
From: Patrick H Dussud <DUSSUD@Jenner.csc.ti.com>
To: Gregor.pa@xerox.com
Cc: common-lisp-object-system@sail.stanford.edu
Subject: Re: method-lambda and apply-method-lambda
In-Reply-To: Msg of Tue, 12 Apr 88 10:21 PDT from Gregor.pa@xerox.com
We have to find some way to converge on this soon. My basic point is
that the genericity should be at the level of add-method and
compute-discriminator-code and that at the level of making method
functions and calling method functions the code should not be generic.
I don't understand your position here.
Here is the issue the way I see it:
- The fact that a generic function calls an effective method establishes a
contract between these two entities.
- This contract has to be abstracted because the implementor should be free to
optimize this time critical operation.
- We want to give access to this operation, namely one wants to call a method
that
belongs to a generic function, with its own set of arguments, with his own set
of next methods (apply-method-lambda).
- We want to give programmers the use of (setf method-function), which is
concerned by the above contract (make-method-function).
In 88-003 the following pieces are connected to this contract besides
apply-method-lambda and make-method-function:
- Compute-discriminator-code, whose result is a piece of code,which when executed
does the method lookup and the calling of the effective method function object.
- Add-method is connected to this protocol because it needs to make sure that
the method added to the generic function will fulfill its part of the contract.
Add-method and compute-discriminator code are generic. Add-method behavior (
deciding if a method is acceptable to the generic function) is implemented by
specialized methods. Compute-discriminator-code will implement its part of the
contract with specialized methods. Now you tell me that the other portions of
the pieces connected to the contract should be wired in for standard-method and
standard-generic-function, and there is no standard way to call a method,
compatible with a generic function, if the method is not a standard-method and
if the generic function is not a standard-generic-function.
I strongly object to this attitude because:
One implementation can define a new pair of (generic-function, method) that have
their own contract (In theory, you write a method on compute-discriminator-code
and add-method), but any portable code that would want to call such a method
would fail because they are using the wrong function. Worse, a user has NO WAY
of telling if he can use apply-method-lambda on a (generic-function, method)
pair, unless:
(and (eql (class-of generic-function)
(symbol-class 'standard-generic-function))
(eql (class-of method)
(symbol-class 'standard-method))) is true.
In my opinion, it breaks one of the goals of the metaclass design:
One can write some portable tools that can use the introspection capability of
MOP.
We may as well forbid any specialization of standard-generic-function and
standard-method.
Patrick.
∂13-Apr-88 1010 Common-Lisp-Object-System-mailer two questions about standard-class
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 13 Apr 88 10:10:12 PDT
Received: from JUNCO.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 381364; Wed 13-Apr-88 13:09:57 EDT
Date: Wed, 13 Apr 88 13:09 EDT
From: Sonya E. Keene <skeene@STONY-BROOK.SCRC.Symbolics.COM>
Subject: two questions about standard-class
To: skeene@STONY-BROOK.SCRC.Symbolics.COM, common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: <19880412155813.0.SKEENE@JUNCO.SCRC.Symbolics.COM>
Message-ID: <19880413170930.6.SKEENE@JUNCO.SCRC.Symbolics.COM>
Date: Tue, 12 Apr 88 11:58 EDT
From: Sonya E. Keene <skeene@STONY-BROOK.SCRC.Symbolics.COM>
A class is considered initialized if its direct superclasses are known.
I don't understand this; how can a class be defined without stating what
its direct superclasses are?
I was also confused about class-default-direct-superclasses. I
understand what it is supposed to do (the method for standard-class
ensures that standard-object is included in the CPL). The
documentation (page 3-14 on my draft) says if there are any supplied
superclasses, this method returns the list of supplied superclasses and
doesn't add standard-object to that list. If there are no supplied
superclasses, this method returns a list containing standard object.
The goal of this approach seems to be not to require standard-object to
be a direct superclass of each class (otherwise the method would always
add standard-object to the list). The assumption seems to be that if
there is a supplied superclass, it already has standard-object in its
CPL. Does this really work? What if you define a class and specify
T to be the only direct superclass?
Well, you can't do that with defclass, anyway, since Chapter 1 states
that you can't use defclass to define subclasses of a built-in class,
and t is a built-in class. However, I don't know whether you can do
the same thing some other way, using the MOP. (later... the 3rd
paragraph below makes me think there is a way)
I'm having trouble understanding some of the ramifications of T being a
built-in class. It seems strange that you can't specify T as a
superclass in the defclass form, yet you get T automatically as a
superclass (by virtue of it being a superclass of standard-object).
The MOP states that standard-object is a standard-class. This implies
that there must be some way to define a standard-class (eg
standard-object) and include a built-in class (eg t) as a superclass.
This mechanism must be different than the normal make-instance of
standard-class, because that calls valid-superclass-p, which signals an
error if the metaclass of the superclass is not EQ with the class being
defined. Or else the method for valid-superclass-p should make an
exception for the class T.
[Whatever the answer to the question, if I stated the goal of the
approach correctly, it should probably be written down in the
documentation.]
∂13-Apr-88 1029 Common-Lisp-Object-System-mailer Re: MAKE-METHOD-FUNCTION and APPLY-METHOD
Received: from Sun.COM by SAIL.Stanford.EDU with TCP; 13 Apr 88 10:28:59 PDT
Received: from snail.sun.com by Sun.COM (4.0/SMI-4.0)
id AA04134; Wed, 13 Apr 88 10:28:19 PDT
Received: from suntana.sun.com by snail.sun.com (4.0/SMI-3.2)
id AA10548; Wed, 13 Apr 88 10:27:30 PDT
Received: from localhost by suntana.sun.com (3.2/SMI-3.2)
id AA07908; Wed, 13 Apr 88 10:20:50 PDT
Message-Id: <8804131720.AA07908@suntana.sun.com>
To: common-lisp-object-system@sail.stanford.edu
Subject: Re: MAKE-METHOD-FUNCTION and APPLY-METHOD
Date: Wed, 13 Apr 88 10:20:48 -0700
From: kempf@Sun.COM
I read back over the mail and did some further thinking on this, and
I've got some additional thoughts on the subject, and a miniproposal.
First to respond to the immediate nature of Gregor's message, I agree
with his point that the code for generic dispatch and the method
function interface are intertwined. Since the code for generic
dispatch has the job of calculating the list of applicable methods
and the effective method (according to Chapter 1), it also has the
job of arranging where that information appears in the environment
of the method function. Some of the possibilities for where to
put it are a "hidden" argument to the method function, a "hidden"
lexical variable in the method function's environment which the
generic dispatch code accesses via some implementation dependent
interface, etc. So, for purposes of arranging for changes in
control flow such as call-next-method, it is not possible to
seperate the code doing the dispatching from the method function
interface.
I think it might be helpful at this point to briefly review the concepts,
functions and macros in Chapters 1, 2, and 3 related to this topic to
see how they fit together. First some definitions from Chapter 1:
Applicable Methods-Given a generic function invocation, the list of
applicable methods are all methods defined on the generic function
whose parameter specializers are satisfied by their corresponding
arguments. The definition of "satisfy" is given in Chapter 1, pg. 1-28.
Effective Method-The effective method is a combination of the
applicable methods according to their precedence order. It is
the code actually executed during the generic function invocation.
Calculating it is the subject of Chapter 1, pp. 1-31-1-35.
Note that these definitions make no mention of dispatcher functions
(or handlers, as they are called in Flavors) nor of method functions.
Generic dispatch is a process, which results in the calculation of
the list of applicable methods and the effective method, and the
application of the effective method to the arguments. Dispatcher
functions, precalculation of the list of applicable methods, etc.
are all optimizations, which must preserve the semantics of this
model in order to be valid. In practice, a dispatcher function
is needed to bundle the control flow associated with generic
dispatch into one place, however.
Now how does this all fit into the metaobject protocol of Chapter 3?
In Chapter 3, pp. 3-59-3-61 list the generic functions. There
are three of interest:
compute-applicable-methods <generic-function> <arguments>
compute-effective-method
<generic-function> <method-combination> <applicable-methods>
These compute the two quantities defined in Chapter 1.
compute-discriminator-code <generic-function>
What does this do? Well, the description in Chapter 3 isn't very clear.
The example uses make-effective-method-function, which isn't documented
anywhere else, and in the invocation of compute-effective-method
the actual parameter list does not match the formal parameter interface
described below the example. Here's my guess as to how the default
method should look:
(defmethod compute-discriminator-code
((generic-function standard-generic-function))
(let
(
(method-combination-object
(generic-function-method-combination generic-function)
)
)
#'(lambda (&rest args)
(let
(
(methods
(compute-applicable-methods generic-function args)
)
)
(check-keyword-arguments generic-function methods args)
(apply
#'compute-effective-method
generic-function
method-combination-object
methods
)
)
) ;lambda
) ;let
) ; compute-discriminator-code
In order for this to work, none of the functions from the metaobject
protocol can be generic, otherwise the metacircularity doesn't terminate.
So Gregor is correct in this point, and Chapter 3 is incorrect, since
compute-effective-method can't be generic. The appropriate place for
specializations is in compute-dispatcher-code. Compute-effective-method
and compute-applicable-methods bundle whatever implementation dependent
mechanism is required to make sure that the environment of method functions
has the necessary information for call-next-method to happen correctly.
Minor niggle: compute-effective-method should probably be called
compute-effective-method-function, since what it is returning is
a function not a method object.
However, Patrick and Dave also have a point, in that there needs to be some
way for creating method functions which installs the special processing
needed to implement call-next-method into the user supplied code.
Perusing Chapter 1 for a moment, we find two macros which look as if
they might help:
make-method <form>
call-method <form>
From the description, these look like hooks into the innards of
compute-effective-method, however, precisely how they might fit
in, I can't figure out.
So we are, indeed, left with a hole in the metaobject protocol which
Patrick's proposed make-method-function would fill. Here is the
interface again:
make-method-function <method> <generic-function> <qualifiers> <specializers>
<lambda-exp> &optional <macroexpand-environment>
This should return a perfectly vaild function which is compilable and
funcallable, with the exception that it may need to be funcalled by
the function returned by compute-discriminator-code to work properly.
The fundamental idea here is that compute-discriminator-code and
make-method-function scheme together to make sure the right code
is generated for unusual changes in control flow like call-next-method.
Both are generic functions, with compute-discriminator-code
specialized on its first argument and make-method-function specialized
on its first and second.
Of course, this analysis overlooks one fundamental point. There are
no primitives in Common Lisp for arranging the transfer of information
needed for things like call-next-method because Common Lisp doesn't
have first class environments. I've got some ideas about simulating
this, but they're not firm so I won't make this lengthy message
even more lengthy by including them.
The miniproposal is this:
1) compute-effective-method, compute-applicable-methods, and
check-keyword-arguments are all functions.
2) make-method-function is implemented as Dave and Patrick have outlined.
3) We figure out how call-method and make-method from Chapter 1 fits
into the metaobject protocol.
jak
∂13-Apr-88 1032 Common-Lisp-Object-System-mailer corrections to Chapter 1
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 13 Apr 88 10:32:50 PDT
Received: from JUNCO.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 381401; Wed 13-Apr-88 13:32:32 EDT
Date: Wed, 13 Apr 88 13:32 EDT
From: Sonya E. Keene <skeene@STONY-BROOK.SCRC.Symbolics.COM>
Subject: corrections to Chapter 1
To: common-lisp-object-system@SAIL.STANFORD.EDU
Message-ID: <19880413173208.7.SKEENE@JUNCO.SCRC.Symbolics.COM>
The section "Determining the Class Precedence List" has examples where
defclass is used to define classes, and the CPL is computed from those
definitions. However, the CPLs shown don't include standard-object
(they do include t). We should really fix this.
The table in Figure 1-1 has two columns, labelled "Predefined Common
Lisp Type" and "Class Precedence List". The first column heading isn't
right; actually, it is correct, but it misses the point. They are
Common Lisp types, but the important thing is that CLOS has classes
corresponding to those types. I think that column heading should be
simply "Classes" or "Predefined Classes" (since "Classes Corresponding
to Common Lisp Types" is too long).
-----------
Also, the section "Standard Meta-objects" says "The class named
standard-object is an instance of the class standard-class and is a
superclass of every class that is an instance of standard-class except
itself." I believe that the MOP (p 3-10) contradicts this statement,
since the class structure-object is an instance of the class
standard-class, yet it doesn't have standard-object as a superclass.
[The previous paragraph seems related to my other message. It seems
like there are some exceptions to the general rules that are not clearly
spelled out. There is a general rule that for instances of
standard-class, all superclasses have to have the same metaclass; but
the implied superclass T is an exception. There is a general rule that
all instances of standard-class include standard-object as a superclass;
but structure-class is an exception.]
∂13-Apr-88 1054 Common-Lisp-Object-System-mailer Re: two questions about standard-class
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 13 Apr 88 10:54:16 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 13 APR 88 09:54:47 PDT
Date: 13 Apr 88 09:54 PDT
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Re: two questions about standard-class
In-reply-to: Sonya E. Keene <skeene@STONY-BROOK.SCRC.Symbolics.COM>'s message of
Tue, 12 Apr 88 11:58 EDT
To: skeene@STONY-BROOK.SCRC.Symbolics.COM
cc: common-lisp-object-system@SAIL.STANFORD.EDU
Message-ID: <880413-095447-16103@Xerox>
A class is considered initialized if its direct superclasses
are known. I don't understand this; how can a class be defined
without stating what its direct superclasses are?
This is a NON-feature that was removed at the meeting. The old idea was to
represent a forward-referenced-class as a class without any direct superclasses.
It was to have been defined by using the functional level
(add-named-class (symbol-class 'standard-class))
where direct-superclasses were not provided. But we decided to have
aforward-referenced-class. CLOS now specifies that direct-superclases be known
at creation time for a standard-class.
I was also confused about class-default-direct-superclasses.
I understand what it is supposed to do (the method for
standard-class ensures that standard-object is included in the
CPL). The documentation (page 3-14 on my draft) says if there are
any supplied superclasses, this method returns the list of supplied
superclasses and doesn't add standard-object to that list. If
there are no supplied superclasses, this method returns a list
containing standard object.
The goal of this approach seems to be not to require
standard-object to be a direct superclass of each class (otherwise
the method would always add standard-object to the list). The
assumption seems to be that if there is a supplied superclass, it
already has standard-object in its CPL. Does this really work?
What if you define a class and specify T to be the only direct
superclass?
The intention is that this should be made to work. It requires the following
not all of which are spelled out explicitly in the writing.
1) Any class in the kernel that is implemented as a standard-class must have
standard-object in its class-precedence list. The only exception is the class
T, if that class is implemented as a standard-class.
2) It is not legal to specify T as a direct superclass of a standard class.
3) In the kernel, the only legal superclass of a standard-class is a
standard-class.
Since all existing standard-classes that can be used as a superclass have
standard-object in their class-precedence-list, if
class-default-direct-superclasses provides standard-object as a
direct-supreclass when no direct-superclasses are specified, this invariant
continues to hold.
Of course, it is possible to program around this restriction using the MOP.
[Whatever the answer to the question, if I stated the goal of
the approach correctly, it should probably be written down in the
documentation.]
Right.
∂13-Apr-88 1123 Common-Lisp-Object-System-mailer Re: Reinitialization
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 13 Apr 88 11:22:52 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 13 APR 88 11:16:06 PDT
Date: 13 Apr 88 11:15 PDT
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Re: Reinitialization
In-reply-to: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>'s message of
Mon, 11 Apr 88 20:35 EDT
To: Moon@STONY-BROOK.SCRC.Symbolics.COM
cc: Common-Lisp-Object-System@SAIL.STANFORD.EDU
Message-ID: <880413-111606-16288@Xerox>
I think Moon's summary was illuminating. Let me try to respond to several of
the issues.
(5) Do we really need four different updating functions? I
think the answer is yes, because user-defined methods could quite
plausibly do different things for each one. The only case I'm not
sure of is whether class-changed and update-instance-structure
really need to be distinguished by user-defined methods. Maybe
they are only distinct because they take different arguments now.
(6) Why do the four updating functions have such inconsistent
interfaces? It makes sense for two of them to take initialization
arguments and the other two to take before & after instance states,
so the real issue is why don't class-changed and
update-instance-structure take similar arguments? I believe that is
only an artifact of the way CLOS evolved; when we abandoned the
attempt to maintain a complete model of class redefinition history,
we also stopped passing a copy of the instance with its old
structure to update-instance-structure. That was because we didn't
have any class to use for that instance. However, just as
class-changed gets a temporary instance with potentially dynamic
extent, update-instance-structure could get a temporary instance of
a temporary class. That would be good, because the information
about what slots were added and removed could be accessed through
the normal Chapter 3 class examination functions, instead of
through special kludgey property lists, and the values of slots
could be accessed the normal way.
Although I am reluctant to change Chapters 1 and 2, I think it
would be justified to make update-instance-structure take two
instances as arguments, the same as class-changed. We should also
change the name of update-instance-structure to make it more
analogous (e.g. class-redefined). It would probably also be okay to
get rid of the distinction between class-changed and
update-instance-structure and just have one generic function for
both, although I haven't thought out the implications of that. We
should be real careful here, as we did think all this stuff out
moderately carefully and we may all have forgotten the reasons by
now.
The forgotten reasons had to do with how one could specify an obsolete class
with the appropriate methods for the old instance. To take our old favorite
example, suppose we wanted to change the definition of the class point. We
start with:
(defclass point ()
((x :accessor point-x :initarg :x)
(y :accessor point-y :initarg :y)))
(defmethod point-rho ((p point)) ;;compute rho from x and y)
(defmethod (setf point-rho) (new-rho (p point)) ;;compute new x and y)
(defmethod point-theta ((p point)) ;;compute theta from x and y)
(defmethod (setf point-theta) (new-theta (p point)) ;;compute new x and y)
We make a few instances and change it to:
(defclass point ()
((rho :accessor point-rho)
(theta :initarg point-theta)))
(defmethod point-x ((p point)) ;;compute x from rho and theta)
(defmethod (setf point-x) (new-x (p point)) ;;compute new rho and theta)
(defmethod point-y ((p point)) ;;compute y from rho and theta)
(defmethod (setf point-y) (new-y (p point)) ;;compute new rho and theta)
(defmethod initialize-instance :after ((p point)) &key :x :y)
;; if x and y are provided, use (setf point-x) (setf point-y)
;; to compute the appropriate values for rho and theta
)
Now, what methods remain on the class for old-point. We discussed
copying (using) the old methods. But we bogged down in trying to understand how
many other methods had to be copied in order to keep the original contract for
point-rho and point-theta. If point-rho called the generic function
(distance x y)
and we later decided to change the name of this function to
(euclidian-distance x y),
what would have to happen for update-instance-structure to work on the old
methods.
We decided that there was no reasonable way to specify what it meant to keep
around a copy of an obsolete-class and its methods, and therefore we had to use
the list descriptions of the old instance.
On the other hand, for class-changed, the methods and classes are current. Hence
it is reasonable to leave in the users hands the problem of keeping the method
for class-changed current.
---
(2) What should be shared among the four updating functions?
There are actually three different things:
(a) the code to fill slots from initialization arguments
(b) the code to fill slots from values of initialization forms
(c) user-defined methods
So far the discussion does not seem to have recognized that we
are talking about three distinct things that could be shared. The
thing we are talking about sharing is -not- simply the primary
method for initialize-instance.
Now, (a) only makes sense for initialize and reinitialize,
since the other two don't have initialization arguments. (b)
doesn't make sense for reinitialize in my opinion, and should only
be done for newly added slots for class-changed and
update-instance-structure, in my opinion (see issue 4). (c)
definitely makes sense for all four, except that only initialize
and reinitialize would pass initialization arguments to the
user-defined methods. By the way, (c) is what Barry Margolin
brought up at X3J13, so that's committee input to which we must
respond.
I want to argue, that under some control, all these make sense for all four
updating functions. The control is simply the list-of-slots-to-consider
argument that Moon proposed for initialize-slots-from-initforms. I will even be
so bold as to suggest some new names, though I would not like to defend them at
great cost.
The four updating functions are:
initialize-new-instance instance &rest initialization-arguments
reinitialize-instance instance &rest initialization-arguments
update-instance-structure instance added-slots discarded-slots property-list
&rest initialization-arguments
update-instance-with-new-class previous current
&rest initialization-arguments
These all call:
initialize-instance instance slots-for-initform
&rest initialization-arguments
The value of slots-for-initform can be a list of slot-names (possibly nil) or T,
which is equivalent to specifying all slots of the instance. For each slot on
the list, if it is uninitialized, and it has an initfunction, it is initialized
with the value of applying the initfunction to NIL.
What value does each of each of the updating functions pass to
initialize-intance for this argument.
The call from initialize-new-instance passes T of course.
The call from reinitialize-instance passes NIL
The call from update-instance-structure passes added-slots
The call from update-instance-with-new-class passes new-slots
Gregor and I previously argued that reinitialize-instance should try to
reinitialize all the slots that were unititialized. We claimed that this would
allow a specialized reinitialization method to call slot-makunbound on just
those slots wanted reinitialized. However, achieving this is still easy. The
specialized method still makes these slots unbound, and passes along the list of
slots that have been made unbound to initialize-instance.
All four pass the initialization-arguments to initialize-instance.
The call to update-instance-structure from the system of course passes NIL as
the initialization-arguments. So does the call to
update-instance-with-new-class. However, an :around method on either of these
latter can compute some interesting initialization-arguments and do a
call-next-method.
As an example of the use, consider the following around method for
update-instance-structure for point the above example:
(defmethod update-instance-structure :around ((p point) ...
;;push :x and :y on the initarg list and call-next-method
)
There is an obvious corresponding example for update-instance-with-new-class.
The upshot is that there is one shared generic function for all four updaters.
Code that is not to be shared is put in the updaters. Code that is to be shared
is put in the shared function. Updating from initforms and from
initialization-arguments can be controlled by what is passed to the shared code.
∂13-Apr-88 1132 Common-Lisp-Object-System-mailer Re: MAKE-METHOD-FUNCTION and APPLY-METHOD
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 13 Apr 88 11:32:15 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 381489; Wed 13-Apr-88 14:31:48 EDT
Date: Wed, 13 Apr 88 14:31 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: MAKE-METHOD-FUNCTION and APPLY-METHOD
To: kempf@Sun.COM
cc: common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: <8804131720.AA07908@suntana.sun.com>
Message-ID: <19880413183155.2.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Wed, 13 Apr 88 10:20:48 -0700
From: kempf@Sun.COM
....
In order for this to work, none of the functions from the metaobject
protocol can be generic, otherwise the metacircularity doesn't terminate.
So Gregor is correct in this point, and Chapter 3 is incorrect, since
compute-effective-method can't be generic.
But compute-effective-method has to be generic! That's the whole basis of
the meta-objectification of method combination. If this is another
non-terminating circularity, then it's another defect in the meta-circular
description of CLOS. In an implementation all these circularities have to
be broken by special-casing, as in any meta-circular interpreter.
....
Minor niggle: compute-effective-method should probably be called
compute-effective-method-function, since what it is returning is
a function not a method object.
What compute-effective-method returns is neither a function nor a method
object. It actually returns a Lisp form. See 88-002 p.1-32. This
probably means your example method for compute-discriminator-code is
wrong because it returns the Lisp form, whereas the one in the version
of chapter 3 that was distributed last month calls the effective method
and returns the result. I can't be sure your code is wrong since I have
yet to see a satisfactory explanation of what compute-discriminator-code
is for.
This is probably a digression from the main discussion, but I thought it
could be important not to let this mistake go by, since it might affect the
result of the main discussion.
∂13-Apr-88 1145 Common-Lisp-Object-System-mailer add-named-xxx
Received: from ti.com by SAIL.Stanford.EDU with TCP; 13 Apr 88 11:45:19 PDT
Received: by ti.com id AA00317; Wed, 13 Apr 88 13:43:17 CDT
Received: from Jenner by tilde id AA06124; Wed, 13 Apr 88 13:40:53 CDT
Message-Id: <2785949234-4097219@Jenner>
Date: Wed, 13 Apr 88 13:47:14 CDT
From: Patrick H Dussud <DUSSUD@Jenner.csc.ti.com>
To: common-lisp-object-system@sail.stanford.edu
Subject: add-named-xxx
Date: Fri, 8 Apr 88 14:52 EDT
From: "David A. Moon" <Moon@scrc-stony-brook.arpa>
Subject: add-named-xxx
Date: Mon, 4 Apr 88 11:20 PDT
From: Gregor.pa@Xerox.COM
After thinking about the above three paragraphs a bit, I think this is
wrong modularity, by your own arguments. I think the caller of
add-named-method should -always- call ensure-generic-function himself.
That is, defmethod really consists of two parts, defining the generic
function if not already defined, and defining/replacing the method.
These two parts should not be combined in the macro expansion. Thus
the arguments to add-named-method should be a prototype method (the
usual kludge for class-discriminating methods) and some keyword arguments
that include a generic function object, qualifiers, specializers, the
method function, and some others that are optional.
I agree with this proposal. At the meeting I proposed that the first argument
be the generic function object, but I think now that this is better. It
provides the right modularity between the class of the generic function and the
class of the method.
Patrick.
∂13-Apr-88 1318 Common-Lisp-Object-System-mailer Chapter 1 and 2 Last Chance Review
Received: from multimax.ARPA by SAIL.Stanford.EDU with TCP; 13 Apr 88 13:18:36 PDT
Received: by multimax.ARPA (5.51/25-eef)
id AA03659; Wed, 13 Apr 88 16:18:16 EDT
Received: from localhost by mist.UUCP (3.2/4.7)
id AA00841; Wed, 13 Apr 88 16:19:25 EDT
Message-Id: <8804132019.AA00841@mist.UUCP>
To: common-lisp-object-system%sail.stanford.edu@multimax
Subject: Chapter 1 and 2 Last Chance Review
Date: Wed, 13 Apr 88 16:19:19 EDT
From: Dan L. Pierson <pierson%mist@multimax.ARPA>
Comments on Chapters 1 and 2 of the CLOS Spec (Edition of 2/8/88)
Page 1-9, Add to the list of things provided by slot options and
class options:
o Specifying the legal data types of the slot contents.
(Of course, this can be found elsewhere in the document,
but my impression on reading this introductory list was
that for some reason you couldn't do this.)
Page 1-11, Paragraphs 3 and 7
Why are reader, writer, and with-slots *required* to be
implemented using SLOT-VALUE? I don't doubt that you have
a good reason, but it's not obvious to a relative novice.
Paragraphs 7 and 8
This implies that WITH-SLOTS can access slots without
accessors but WITH-ACCESSORS can't. This is reasonable
but should probably be made explicit. Some people may
feel that this maked WITH-SLOTS unsafe.
Page 1-13, Paragraph 4
This paragraph appears self-contradictory. I think that
it means that portable code cannot depend on slot types
since:
(1) Some implementations may not provide type errors
(therefore reducing the value of slot types for
debugging), and
(2) Calls from outside the package may store incorrect
types (so even if your portable code is self-consistent
you could wind up with undetected type errors).
The wording of this paragraph leads me to suspect that
this issue has already been argued to death on the CLOS list.
Page 1-26, Paragraph 2, Sentence 2
The following are my exact notes as I read this section:
What about methods in both old and new? Are they "added"?
If so, in what way is this definition different from
saying that the "contents" of the old generic function are
trashed and replaced by the new generic function? AHA!
Some methods could have been defined by DEFMETHOD, but the
wording is still confusing.
Paragraph 6, Sentence 3
The wording is a bit confusing.
Page 1-28, Paragraph 2, Sentence 4 and example line
Has this been submitted to cleanup? I don't recognize it.
Page 1.29, Paragraph 1
The wording implies that:
(EQUAL '(A (B C)) '((A B) C))
is T, which is certainly false. Note that cleanup is
entertaining proposal to flush EQUAL and EQUALP.
Page 1-32, At this point I made a note:
In general, this draft details the complex, general case
before the simpler, common special case. This *may* be
appropriate for a standards document but it certainly
isn't for a manual.
Page 2-27, Next to last paragraph
Can extension slot options appear more than once in a
single slot description (it appears reasonable, but it's
not clear from this whether it's legal).
Last paragraph
The slot can also be accessed by WITH-SLOTS, since
WITH-SLOTS uses SLOT-VALUE.
Page 2-35, Paragraphs 7 and 8
These paragraphs don't specify how to distinguish a
predicate from the first keyword option since they are
both distinguished by being symbols other than * (or NIL).
∂13-Apr-88 1344 Common-Lisp-Object-System-mailer add-named-xxx
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 13 Apr 88 13:43:51 PDT
Received: from Semillon.ms by ArpaGateway.ms ; 13 APR 88 13:39:31 PDT
Date: Wed, 13 Apr 88 13:38 PDT
From: Gregor.pa@Xerox.COM
Subject: add-named-xxx
To: Patrick H Dussud <DUSSUD@Jenner.csc.ti.com>
cc: common-lisp-object-system@SAIL.STANFORD.EDU
Fcc: BD:>Gregor>mail>outgoing-mail-2.text
In-Reply-To: <2785949234-4097219@Jenner>
Message-ID: <880413133840.1.GREGOR@SPIFF.parc.xerox.com>
Line-fold: no
Date: Wed, 13 Apr 88 13:47:14 CDT
From: Patrick H Dussud <DUSSUD@Jenner.csc.ti.com>
Date: Fri, 8 Apr 88 14:52 EDT
From: "David A. Moon" <Moon@scrc-stony-brook.arpa>
Subject: add-named-xxx
Date: Mon, 4 Apr 88 11:20 PDT
From: Gregor.pa@Xerox.COM
After thinking about the above three paragraphs a bit, I think this is
wrong modularity, by your own arguments. I think the caller of
add-named-method should -always- call ensure-generic-function himself.
That is, defmethod really consists of two parts, defining the generic
function if not already defined, and defining/replacing the method.
These two parts should not be combined in the macro expansion. Thus
the arguments to add-named-method should be a prototype method (the
usual kludge for class-discriminating methods) and some keyword arguments
that include a generic function object, qualifiers, specializers, the
method function, and some others that are optional.
I agree with this proposal. At the meeting I proposed that the first argument
be the generic function object, but I think now that this is better. It
provides the right modularity between the class of the generic function and the
class of the method.
I also like this. We will put something like it in the next draft.
-------
∂13-Apr-88 1414 Common-Lisp-Object-System-mailer Chapter 1 and 2 Last Chance Review
Received: from multimax.ARPA by SAIL.Stanford.EDU with TCP; 13 Apr 88 14:14:11 PDT
Received: by multimax.ARPA (5.51/25-eef)
id AA04140; Wed, 13 Apr 88 17:13:39 EDT
Received: from JUNCO.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 381660; Wed 13-Apr-88 17:13:02 EDT
Date: Wed, 13 Apr 88 17:12 EDT
From: Sonya E. Keene <skeene@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Chapter 1 and 2 Last Chance Review
To: pierson%mist@MULTIMAX.ARPA
Cc: common-lisp-object-system%sail.stanford.edu@MULTIMAX.ARPA
In-Reply-To: <8804132019.AA00841@mist.UUCP>
Message-Id: <19880413211239.3.SKEENE@JUNCO.SCRC.Symbolics.COM>
Date: Wed, 13 Apr 88 16:19:19 EDT
From: Dan L. Pierson <pierson%mist@multimax.ARPA>
Comments on Chapters 1 and 2 of the CLOS Spec (Edition of 2/8/88)
Hey, you actually read it! Thanks for the useful comments.
Page 1-9, Add to the list of things provided by slot options and
class options:
o Specifying the legal data types of the slot contents.
(Of course, this can be found elsewhere in the document,
but my impression on reading this introductory list was
that for some reason you couldn't do this.)
Good idea. (I think originally this section was intended to be an
overview of the more interesting features, but eventually all of the
features got added except for the :type constraint.)
Page 1-11, Paragraphs 3 and 7
Why are reader, writer, and with-slots *required* to be
implemented using SLOT-VALUE? I don't doubt that you have
a good reason, but it's not obvious to a relative novice.
Some background is: we know that any implementation of CLOS will have
to have a primitive that does what SLOT-VALUE does. Otherwise you
couldn't implement readers or writers at all. So we document that
primitive (SLOT-VALUE) so that all implementations give it the same
name, arguments, and behavior, and therefore users can write portable
code that calls it. The goal is to expose the underlying mechanisms
if they are generally useful.
The purpose of WITH-SLOTS is just to be a shortcut syntax for using
SLOT-VALUE all over the place. It's "required" to be implemented with
SLOT-VALUE because that's just the definition of what it does.
As for why readers and writers are "required" to be implemented using
SLOT-VALUE, hmmm, I'm not sure. I don't think there's any reason why
you wouldn't implement readers and writers with SLOT-VALUE, since
SLOT-VALUE does the thing you want to do.
Paragraphs 7 and 8
This implies that WITH-SLOTS can access slots without
accessors but WITH-ACCESSORS can't. This is reasonable
but should probably be made explicit. Some people may
feel that this maked WITH-SLOTS unsafe.
The implication was intended; that's the difference between the two
macros. I personally agree with people who feel WITH-SLOTS is unsafe.
We could add a sentence to imply what we mean more directly.
Page 1-13, Paragraph 4
This paragraph appears self-contradictory. I think that
it means that portable code cannot depend on slot types
since:
(1) Some implementations may not provide type errors
(therefore reducing the value of slot types for
debugging), and
Yes, it does mean (1). This is also said in the first bullet on page
1-13.
(2) Calls from outside the package may store incorrect
types (so even if your portable code is self-consistent
you could wind up with undetected type errors).
I don't know what you mean by (2).
The wording of this paragraph leads me to suspect that
this issue has already been argued to death on the CLOS list.
(Don't let the wording fool you. We argue every issue to death.)
Page 1-26, Paragraph 2, Sentence 2
The following are my exact notes as I read this section:
What about methods in both old and new? Are they "added"?
If so, in what way is this definition different from
saying that the "contents" of the old generic function are
trashed and replaced by the new generic function? AHA!
Some methods could have been defined by DEFMETHOD, but the
wording is still confusing.
Your point about "some methods could have been defined by DEFMETHOD" is
correct, and we should probably add a sentence to that effect.
Page 1-32, At this point I made a note:
In general, this draft details the complex, general case
before the simpler, common special case.
The section in page 1-32 doesn't present the simpler, common special
case first and then get into details that include the hairy, rare cases.
It does all cases at once. This is a very central part of CLOS, and
it is somewhat complex, so readers are going to have to read the section
on Method Selection and Combination a couple times or more. I think
it's OK as it is.
This *may* be
appropriate for a standards document but it certainly
isn't for a manual.
Right. Manuals have a lot more freedom.
Page 2-27, Next to last paragraph
Can extension slot options appear more than once in a
single slot description (it appears reasonable, but it's
not clear from this whether it's legal).
Last paragraph
The slot can also be accessed by WITH-SLOTS, since
WITH-SLOTS uses SLOT-VALUE.
Do you think we need to say that explicitly? Since WITH-SLOTS is
defined in terms of SLOT-VALUE, I think most readers will figure this
out, as you did.
Page 2-35, Paragraphs 7 and 8
These paragraphs don't specify how to distinguish a
predicate from the first keyword option since they are
both distinguished by being symbols other than * (or NIL).
∂13-Apr-88 1435 Common-Lisp-Object-System-mailer Re: Chapter 1 and 2 Last Chance Review
Received: from multimax.ARPA by SAIL.Stanford.EDU with TCP; 13 Apr 88 14:34:58 PDT
Received: by multimax.ARPA (5.51/25-eef)
id AA04246; Wed, 13 Apr 88 17:35:02 EDT
Received: from localhost by mist.UUCP (3.2/4.7)
id AA01079; Wed, 13 Apr 88 17:36:12 EDT
Message-Id: <8804132136.AA01079@mist.UUCP>
To: "Sonya E. Keene" <skeene%STONY-BROOK.SCRC.Symbolics.COM@multimax>
Cc: common-lisp-object-system%sail.stanford.edu@MULTIMAX.ARPA
Subject: Re: Chapter 1 and 2 Last Chance Review
In-Reply-To: Your message of Wed, 13 Apr 88 17:12:00 -0400.
<19880413211239.3.SKEENE@JUNCO.SCRC.Symbolics.COM>
Date: Wed, 13 Apr 88 17:36:10 EDT
From: Dan L. Pierson <pierson%mist@multimax.ARPA>
(2) Calls from outside the package may store incorrect
types (so even if your portable code is self-consistent
you could wind up with undetected type errors).
I don't know what you mean by (2).
Let's say you're implementing a window system which has slots
WINDOW-WIDTH and WINDOW-HEIGHT. You define these slots to be of type
integer *and* ensure that your code never puts a non-integer in them.
You still have to explicitly check the type of the slot value every
time any code that you didn't write could have run because a user
program could have put a non-integer in the slot without getting an
error in some implementations.
∂13-Apr-88 1714 Common-Lisp-Object-System-mailer Re: MAKE-METHOD-FUNCTION and APPLY-METHOD
Received: from Sun.COM by SAIL.Stanford.EDU with TCP; 13 Apr 88 17:14:46 PDT
Received: from snail.sun.com by Sun.COM (4.0/SMI-4.0)
id AA11703; Wed, 13 Apr 88 17:13:40 PDT
Received: from suntana.sun.com by snail.sun.com (4.0/SMI-3.2)
id AA24132; Wed, 13 Apr 88 17:12:59 PDT
Received: from localhost by suntana.sun.com (3.2/SMI-3.2)
id AA21809; Wed, 13 Apr 88 17:06:24 PDT
Message-Id: <8804140006.AA21809@suntana.sun.com>
To: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Cc: kempf@Sun.COM, common-lisp-object-system@SAIL.STANFORD.EDU
Subject: Re: MAKE-METHOD-FUNCTION and APPLY-METHOD
In-Reply-To: Your message of Wed, 13 Apr 88 14:31:00 -0400.
<19880413183155.2.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Wed, 13 Apr 88 17:06:22 -0700
From: kempf@Sun.COM
>But compute-effective-method has to be generic! That's the whole basis of
>the meta-objectification of method combination. If this is another
>non-terminating circularity, then it's another defect in the meta-circular
>description of CLOS. In an implementation all these circularities have to
>be broken by special-casing, as in any meta-circular interpreter.
OK, I'll buy that. I misunderstood the specification for
compute-effective-method. Further comment on the implications below,
plus the special casing which is needed.
>What compute-effective-method returns is neither a function nor a method
>object. It actually returns a Lisp form. See 88-002 p.1-32. This
Right. That explains what the undocumented function
make-effective-method-function does in the example on pg. 3-59. It
takes the generic function and the effective method form, and
returns a function which can be applied to start the method
rolling. It also hides the implementation dependencies necessary
for setting up the environment so that call-next-method works.
And that is where the metacircular recursion bottoms out, since
it returns a function and not a generic function.
>I can't be sure your code is wrong since I have
>yet to see a satisfactory explanation of what compute-discriminator-code
>is for.
compute-discriminator-code does precisely the same thing for generic
dispatch that compute-effective-method does for method combination.
It is where code for customized generic dispatch gets generated.
It needs to work together with make-method-function to assure that
customized control flow changes like call-next-method get done correctly,
because the generic dispatch code has to know what sort of interface
the method functions require and what specialized features of the
execution environment need to be set up. In the default case,
make-effective-method-function takes care of most of that. Here's
what I'd expect compute-discriminator-code to look like in the
default case:
(defmethod compute-discriminator-code
((generic-function standard-generic-function)
(method-combination standard-method-combination)
)
#'(lambda (&rest args)
(let*
(
(applicable-methods
(compute-applicable-methods generic-function args)
)
(effective-method-form
(compute-standard-effective-method-form
generic-function
method-combination
applicable-methods
)
)
(effective-method-function
(make-effective-method-function
generic-function
effective-method-form
)
)
)
(check-keyword-arguments generic-function methods args)
(apply effective-method-function args)
)
) ;lambda
) ; compute-discriminator-code
There are a couple things to note here:
1) Everything called by compute-discriminator-code is a function.
These are: compute-applicable-methods, compute-standard-effective-method-form,
and make-effective-method-function. If this is not the case,
the metacircularity does not bottom out.
2) New in this list is compute-standard-effective-method-form. It takes
the generic function, a standard-method-combination object, and the
list of applicable methods, and returns the effective method form.
The compute-effective-method method for standard-method-combination
would have the application of this function as its body. This is
the special casing. Side note: the method combination object
might not be needed as an argument, since the function already
knows the kind of method combination.
3) The creation of the dispatcher function is parameterized by both
the generic function and the method combination. There is really no
choice here, because the algorithm for calculating the effective
method depends on both the list of applicable methods (which the
generic function provides) and the method combination type.
4) Functions similar to compute-standard-effective-method-form would be
needed for other system provided method combination types, of course.
I think some of the problems in the discussion about bottoming out
of metacircularity come from the fact that we made method combination
metacircular without taking into account that calculating the
effective method, which is parameterized by method combination,
is a fundamental part of generic dispatch, and therefore
we introduced an infinite loop. This proposal unrolls the loop.
As an example of how this could be used with make-method-function to
introduce a customized control flow primitive, consider the
following modification, which we had suggested in the specification
paper. It allows any more general method to be invoked, depending
on the arguments, rather than just the next most general method:
;;uses no method combination, and simply takes the first method
;; on the list to start the ball rolling.
(defmethod compute-discriminator-code
((generic-function my-generic-function) method-combination)
#'(lambda (&rest args)
(let*
(
(applicable-methods
(my-compute-applicable-methods generic-function args)
)
)
(apply (method-function (car applicable-methods))
(cdr applicable-methods)
args
)
)
) ;lambda
) ; compute-discriminator-code
(defmethod make-method-function
((method my-method)
(generic-function my-generic-function)
specializers
qualifiers
lambda-exp
&optional macroexpand-env
)
`(lambda (rest-applicable-methods &rest args)
(flet
(
(my-call-next-method (&rest call-args)
(let*
(
(matching-method
(get-more-general-method rest-applicable-methods call-args)
)
(next-rest-applicable-methods
(member matching-method rest-applicable-methods)
)
)
(if matching-method
(apply (method-function matching-method)
(cdr next-rest-applicable-methods)
call-args
)
(apply #'no-applicable-method ,generic-function call-args)
)
) ;let*
) ;my-call-next-method
)
(apply (function ,lambda-exp) args)
) ;flet
) ;lambda
) ;make-method-function
Here, compute-discriminator-code and make-method-function implement
the communication of the applicable method list via a hidden argument.
The only thing I don't like about this is that compute-discriminator-code
returns a function object while make-method-function returns the code
for a function (maybe the names should be interchanged?). But, given
that function objects are atomic in Common Lisp, there probably isn't
any better way to do this, except by having compute-discriminator-code
return the code, so the caller would have to turn it into a function,
or have make-method-function call eval on the code to make the
function.
Does this make any sense? The fact that we're having such a hard time
converging on this is an indication to me that we're venturing into
little understood territory. However, as Gregor mentioned, we need
to come to convergence on this soon.
jak
∂14-Apr-88 0607 Common-Lisp-Object-System-mailer promises
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 14 Apr 88 06:07:13 PDT
Received: from JUNCO.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 382034; Thu 14-Apr-88 09:07:06 EDT
Date: Thu, 14 Apr 88 09:06 EDT
From: Sonya E. Keene <skeene@STONY-BROOK.SCRC.Symbolics.COM>
Subject: promises
To: common-lisp-object-system@SAIL.STANFORD.EDU
Message-ID: <19880414130645.8.SKEENE@JUNCO.SCRC.Symbolics.COM>
At the vote at the last meeting, we promised to respond to people's
comments on Chapters 1 and 2 "in writing". Does this mean we can
respond to them individually, or do we have to collect all the comments
and responses and present that information to the X3J13 committee as a
whole?
∂14-Apr-88 0630 Common-Lisp-Object-System-mailer Re: Chapter 1 and 2 Last Chance Review
Received: from multimax.ARPA by SAIL.Stanford.EDU with TCP; 14 Apr 88 06:30:26 PDT
Received: by multimax.ARPA (5.51/25-eef)
id AA00517; Thu, 14 Apr 88 09:28:40 EDT
Received: from JUNCO.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 382033; Thu 14-Apr-88 09:05:18 EDT
Date: Thu, 14 Apr 88 09:04 EDT
From: Sonya E. Keene <skeene@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: Chapter 1 and 2 Last Chance Review
To: pierson%mist@MULTIMAX.ARPA
Cc: skeene%STONY-BROOK.SCRC.Symbolics.COM@MULTIMAX.ARPA,
common-lisp-object-system%sail.stanford.edu@MULTIMAX.ARPA
In-Reply-To: <8804132136.AA01079@mist.UUCP>
Message-Id: <19880414130455.7.SKEENE@JUNCO.SCRC.Symbolics.COM>
Date: Wed, 13 Apr 88 17:36:10 EDT
From: Dan L. Pierson <pierson%mist@multimax.ARPA>
(2) Calls from outside the package may store incorrect
types (so even if your portable code is self-consistent
you could wind up with undetected type errors).
I don't know what you mean by (2).
Let's say you're implementing a window system which has slots
WINDOW-WIDTH and WINDOW-HEIGHT. You define these slots to be of type
integer *and* ensure that your code never puts a non-integer in them.
You still have to explicitly check the type of the slot value every
time any code that you didn't write could have run because a user
program could have put a non-integer in the slot without getting an
error in some implementations.
OK. You're right, you would have to do that if you want to have
portable code. You can do it pretty easily by defining two methods
for the writer generic function yourself (instead of using an
automatically-generated method). One method specializes the new value
parameter on integer (the desired type of value), and writes the value
into the slot. The other method doesn't specialize the new value
parameter, so it gets selected on undesired types of values, and it
signals an error.
Or you could define a before-method on the writer that checks the type
of the new value and signals an error if it isn't an integer. If it is
an integer, the before-method just returns and lets the primary method
write the value into the slot.
If you do this type-checking in methods for accessors, you have to
depend on your clients calling the accessors and not using slot-value.
∂14-Apr-88 0950 Common-Lisp-Object-System-mailer promises
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 14 Apr 88 09:50:42 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 382230; Thu 14-Apr-88 12:50:31 EDT
Date: Thu, 14 Apr 88 12:50 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: promises
To: common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: <19880414130645.8.SKEENE@JUNCO.SCRC.Symbolics.COM>
Message-ID: <19880414165040.2.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Thu, 14 Apr 88 09:06 EDT
From: Sonya E. Keene <skeene@STONY-BROOK.SCRC.Symbolics.COM>
At the vote at the last meeting, we promised to respond to people's
comments on Chapters 1 and 2 "in writing". Does this mean we can
respond to them individually, or do we have to collect all the comments
and responses and present that information to the X3J13 committee as a
whole?
I have yet to read the X3 rule book, but my guess would be that we should
do the latter. To do that, we need to designate someone as the editor of this,
to maintain the collection of information and make sure nothing has been lost.
I've been saving the 3 or 4 pieces of electronic mail that seemed to belong to
this. I understand there were also some written comments from Kathy Chapman.
I'm not aware of any other comments received yet; has anyone received any?
∂14-Apr-88 1021 Common-Lisp-Object-System-mailer Re: promises
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 14 Apr 88 10:21:37 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 14 APR 88 10:18:50 PDT
Date: 14 Apr 88 10:17 PDT
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Re: promises
In-reply-to: Sonya E. Keene <skeene@STONY-BROOK.SCRC.Symbolics.COM>'s message of
Thu, 14 Apr 88 09:06 EDT
To: skeene@STONY-BROOK.SCRC.Symbolics.COM
cc: common-lisp-object-system@SAIL.STANFORD.EDU
Message-ID: <880414-101850-18376@Xerox>
I think we have to keep a record of all "official responses". We should make
sure that we can extract these from the archive. But I think we need to ask
Mathis what is official policy for X3.
danny
∂14-Apr-88 1130 Common-Lisp-Object-System-mailer CLOS consortium
Received: from uunet.UU.NET by SAIL.Stanford.EDU with TCP; 14 Apr 88 11:30:39 PDT
Received: from mcvax.UUCP by uunet.UU.NET (5.54/1.14) with UUCP
id AA09658; Thu, 14 Apr 88 14:30:26 EDT
Received: by mcvax.cwi.nl; Thu, 14 Apr 88 15:25:41 +0200 (MET)
Received: from cl.cam.ac.uk by kestrel.Ukc.AC.UK via Janet (UKC CAMEL FTP)
id aa10821; 13 Apr 88 20:18 BST
Via: harlqn; 13 Apr 88 20:16 BST (UK.AC.Cam.CL.Jenny)
Received: from jung.harlqn.uucp (jung) by harlqn.uucp; Wed, 13 Apr 88 19:30:17 BST
Received: by jung.harlqn.uucp (3.2/SMI-3.2)
id AA15523; Wed, 13 Apr 88 19:28:50 BST
Date: Wed, 13 Apr 88 19:28:50 BST
Message-Id: <8804131828.AA15523@jung.harlqn.uucp>
To: common-lisp-object-system@sail.stanford.edu
From: Chris Richardson <mcvax!harlqn.co.uk!chris@uunet.UU.NET>
Sender: mcvax!harlqn.co.uk!chris@uunet.UU.NET
Subject: CLOS consortium
Some time ago I saw a news item proposing that a
consortium should be set up to develop a high performance
implementation of CLOS
Has this proposal been developed further?
Thanks.
--chris richardson (ukc!harlqn!chris), Harlequin Ltd, England
∂14-Apr-88 1135 Common-Lisp-Object-System-mailer Responses
To: common-lisp-object-system@SAIL.Stanford.EDU
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>
last[cls,lsp] is a file with what I take to be remarks to
which we must respond.
-rpg-
∂14-Apr-88 1147 Common-Lisp-Object-System-mailer Re: dependent update protocol
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 14 Apr 88 11:47:19 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 14 APR 88 11:42:57 PDT
Date: 14 Apr 88 11:42 PDT
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Re: dependent update protocol
In-reply-to: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>'s message of
Mon, 11 Apr 88 15:50 EDT
To: Moon@STONY-BROOK.SCRC.Symbolics.COM
cc: common-lisp-object-system@SAIL.STANFORD.EDU
Message-ID: <880414-114257-18564@Xerox>
I am answering Moon's message, but will only include the parts that I want to
comment on.
\Defmeth map-dependents ((instance
updatable-object-mixin) function args) For all dependents of
instance, applies function to instance, the dependent and
args.
It's usually better not to try to pass extra args through a
mapping function; instead the function being mapped can be a
closure that knows the extra args. This is more flexible, and is
how all eight functions in CLtL whose names start with "map" work.
Thus I would make map-dependents take only two arguments.
(defmethod reinitialize-instance :around
((object updatable-object-mixin) &rest reinitargs)
(let ((before (apply #'before-reinitialization object reinitargs)))
(call-next-method)
(let ((update-args
(apply #'after-reinitialization object before reinitargs)))
(map-dependents object #'update-dependent object update-args))))
I agree.
I don't see how this can work if reinitialize-instance changes
the set of dependents. The map-dependents will map over the new
dependents, and any old dependents that were removed will never be
updated. Maybe you can say that remove-dependent, or by convention
each caller of it, calls update-dependent or a variant of it on the
dependent being removed.
I don't see this as a problem. The semantics of dependency that I see are that
a dependent wants to know when its "master" changes. But if it is no longer a
dependent, then it has no more "need to know". It may then become a dependent
on something else, and will be updated at that time. If one wants to ensure
that an object of type T1 takes special action when a dependency is removed,
then an :after method on remove-dependent can do whatever is necessary.
Also, since the style you propose depends on three methods for
three different generic functions to be kept in sync, and does
something unpredictable without necessarily signalling an error if
one of the methods is left out, it doesn't seem very robust. I
would prefer to see either a more abstract data structure than a
list, so that leaving out a method (or forgetting to call cdr) for
one class would not damage the data seen by other class's methods,
or else to use one generic function instead of three, so that all
the code for one class would be in a single place and hence less
likely to be out of sync. In the latter case, this generic
function would be called multiple times and one of its arguments
would indicate whether state was being collected or distributed.
The intent of the before-reinitialization is to capture the appropriate state of
the instance before it changes, and that of after-reinitialization is to capture
some summary of what changed (note that these methods only look at the state of
the master object, and the inputs, not any dependent). An alternative I prefer
(please comment) is to specify that before-reinitialization and
after-reinitialization both return property lists.
For example, I would specify that before-reinitialization for standard-class
returns a property list that contains (at least) old direct-superclasses,
direct-slots, and direct-options if these arguments are provided as reinit-args.
After-reinitialization for standard-class returns a property list which has
properties with value T for each of direct-superclasses, direct-slots, and
direct-options if that info in the class changed.
By specifying property lists, the shadowing properties are well undertood, and
it is easy to arrange for noninterference with superclass properties. Also
with this form, error checking can be implemented as property list or argument
list checks.
∂14-Apr-88 1202 Common-Lisp-Object-System-mailer Re: MAKE-METHOD-FUNCTION and APPLY-METHOD
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 14 Apr 88 12:01:49 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 382411; Thu 14-Apr-88 15:01:37 EDT
Date: Thu, 14 Apr 88 15:01 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: MAKE-METHOD-FUNCTION and APPLY-METHOD
To: common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: <8804140006.AA21809@suntana.sun.com>
Message-ID: <19880414190146.3.MOON@EUPHRATES.SCRC.Symbolics.COM>
Comments on the rest of your message later, but two comments now:
Date: Wed, 13 Apr 88 17:06:22 -0700
From: kempf@Sun.COM
3) The creation of the dispatcher function is parameterized by both
the generic function and the method combination. There is really no
choice here, because the algorithm for calculating the effective
method depends on both the list of applicable methods (which the
generic function provides) and the method combination type.
The method combination can be obtained from the generic function by
calling generic-function-method-combination, so the only reason to
pass it as an argument to compute-discriminator-code is if it's needed
for method selection.
I think some of the problems in the discussion about bottoming out
of metacircularity come from the fact that we made method combination
metacircular without taking into account that calculating the
effective method, which is parameterized by method combination,
is a fundamental part of generic dispatch, and therefore
we introduced an infinite loop. This proposal unrolls the loop.
I see. Here's another way to write it that might make what you're doing
easier to understand:
(defmethod compute-discriminator-code
((generic-function standard-generic-function))
(let ((f (get-handler-for #'compute-effective-method
generic-function
(generic-function-method-combination
generic-function)
nil)))
#'(lambda (&rest args)
(let* ((applicable-methods
(compute-applicable-methods generic-function args))
(effective-method-form
(funcall f generic-function
(generic-function-method-combination
generic-function)
applicable-methods)) ....
get-handler-for is a new primitive that provides a proper separation
between the act of finding the effective method function and the act of
applying it. This pulls the generic dispatch for
compute-effective-method out of the loop. This is mere code hoisting,
except that it shows where to put the special case to break the
circularity.
Reactions?
∂14-Apr-88 1352 Common-Lisp-Object-System-mailer Re: MAKE-METHOD-FUNCTION and APPLY-METHOD
Received: from Sun.COM by SAIL.Stanford.EDU with TCP; 14 Apr 88 13:52:24 PDT
Received: from snail.sun.com by Sun.COM (4.0/SMI-4.0)
id AA24022; Thu, 14 Apr 88 13:51:22 PDT
Received: from suntana.sun.com by snail.sun.com (4.0/SMI-3.2)
id AA19841; Thu, 14 Apr 88 13:50:41 PDT
Received: from localhost by suntana.sun.com (3.2/SMI-3.2)
id AA00351; Thu, 14 Apr 88 13:44:09 PDT
Message-Id: <8804142044.AA00351@suntana.sun.com>
To: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Cc: common-lisp-object-system@SAIL.STANFORD.EDU
Subject: Re: MAKE-METHOD-FUNCTION and APPLY-METHOD
In-Reply-To: Your message of Thu, 14 Apr 88 15:01:00 -0400.
<19880414190146.3.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Thu, 14 Apr 88 13:44:07 -0700
From: kempf@Sun.COM
>The method combination can be obtained from the generic function by
>calling generic-function-method-combination, so the only reason to
>pass it as an argument to compute-discriminator-code is if it's needed
>for method selection.
Right, so it can go back to just one parameter.
>I see. Here's another way to write it that might make what you're doing
>easier to understand:
>
> (defmethod compute-discriminator-code
> ((generic-function standard-generic-function))
> (let ((f (get-handler-for #'compute-effective-method
> generic-function
> (generic-function-method-combination
> generic-function)
> nil)))
> #'(lambda (&rest args)
> (let* ((applicable-methods
> (compute-applicable-methods generic-function args))
> (effective-method-form
> (funcall f generic-function
> (generic-function-method-combination
> generic-function)
> applicable-methods)) ....
>
>get-handler-for is a new primitive that provides a proper separation
>between the act of finding the effective method function and the act of
>applying it. This pulls the generic dispatch for
>compute-effective-method out of the loop. This is mere code hoisting,
>except that it shows where to put the special case to break the
>circularity.
Yes, this would be a more general primitive. This looks good.
Reactions from others? Patrick, Gregor? It would be particularly interesting
to hear how people feel about letting compute-discriminator-code and
make-method-function negotiate their own contract for the calling interface
in method metaclasses other than the default.
jak
∂14-Apr-88 1431 Common-Lisp-Object-System-mailer Re: MAKE-METHOD-FUNCTION and APPLY-METHOD
Received: from ti.com by SAIL.Stanford.EDU with TCP; 14 Apr 88 14:30:49 PDT
Received: by ti.com id AA07954; Thu, 14 Apr 88 16:28:43 CDT
Received: from Jenner by tilde id AA29151; Thu, 14 Apr 88 16:21:06 CDT
Message-Id: <2786045229-9864708@Jenner>
Date: Thu, 14 Apr 88 16:27:09 CDT
From: Patrick H Dussud <DUSSUD@Jenner.csc.ti.com>
To: common-lisp-object-system@sail.stanford.edu
Subject: Re: MAKE-METHOD-FUNCTION and APPLY-METHOD
In-Reply-To: Msg of Thu, 14 Apr 88 15:01 EDT from "David A. Moon" <Moon@scrc-stony-brook.arpa>
I see. Here's another way to write it that might make what you're doing
easier to understand:
(defmethod compute-discriminator-code
((generic-function standard-generic-function))
(let ((f (get-handler-for #'compute-effective-method
generic-function
(generic-function-method-combination
generic-function)
nil)))
#'(lambda (&rest args)
(let* ((applicable-methods
(compute-applicable-methods generic-function args))
(effective-method-form
(funcall f generic-function
(generic-function-method-combination
generic-function)
applicable-methods)) ....
get-handler-for is a new primitive that provides a proper separation
between the act of finding the effective method function and the act of
applying it. This pulls the generic dispatch for
compute-effective-method out of the loop. This is mere code hoisting,
except that it shows where to put the special case to break the
circularity.
Reactions?
I am not too concerned by the circularity. It amounts to a bootstrapping
problem. All the chapter 3 generic function are instances of
standard-generic-function. An implementation will code the discriminator code
for standard generic functions in a way that it does not have to interpret its
way through compute-applicable-method, compute-effective-method, etc. every
time those standard-generic-functions are called. However it probably has to do
it at least once sometimes.
I don't think that the guts of compute-discriminator-code, and the code it
produces should be standardized. I don't see any problem in exposing the sub
primitives as long as they don't have to be not called every time a generic
function is called. I think it should be explained the same way make-instance
is explained: logically, things happen like this (gregor code, kempf code or
moon's code), but implementations can short cut any of this as long as the
desired effect is obtained.
Patrick.
∂14-Apr-88 1514 Common-Lisp-Object-System-mailer Re: method-lambda and apply-method-lambda
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 14 Apr 88 15:14:34 PDT
Received: from Semillon.ms by ArpaGateway.ms ; 14 APR 88 15:10:58 PDT
Date: Thu, 14 Apr 88 15:09 PDT
From: Gregor.pa@Xerox.COM
Subject: Re: method-lambda and apply-method-lambda
To: Patrick H Dussud <DUSSUD@Jenner.csc.ti.com>, kempf@Sun.COM, David A. Moon
<Moon@STONY-BROOK.SCRC.Symbolics.COM>
cc: common-lisp-object-system@SAIL.STANFORD.EDU
Fcc: BD:>Gregor>mail>outgoing-mail-2.text
In-Reply-To: <2785937331-3382088@Jenner>,
<8804131720.AA07908@suntana.sun.com>,
<19880413183155.2.MOON@EUPHRATES.SCRC.Symbolics.COM>,
<8804140006.AA21809@suntana.sun.com>,
<8804142044.AA00351@suntana.sun.com>,
<19880414190146.3.MOON@EUPHRATES.SCRC.Symbolics.COM>
Message-ID: <880414150957.6.GREGOR@SPIFF.parc.xerox.com>
Line-fold: no
I am not even going to try to yank in all the relevant parts of all
these messages and match them up where they meet. After talking to
Patrick on the phone and thinking long and hard about what he was
proposing, I now believe it can work and is a good idea. So this
message just summarizes what I believe is a correct proposal.
make-method-function (generic-function method lambda-list body)
This is a generic function. It tends to be specialized on the class of
the generic-function and method arguments. The returned result
satisfies the criterion outlined by Moon in one of his messages.
apply-method-function generic-function method function info &rest args
This is also a generic function. It tends to be specialied on its first
two arguments as well. For the case where generic-function and method
are both standard, the info argument is a list of the next methods.
Each of these functions are generic on both the generic-function and the
method to reflect the fact that both are involved in determining the
method calling contract.
The metacircularity can bottom out without problems because the
standard-method on compute discriminator code can tell than any of the
calls it should make to apply-method-function will actually end up
invoking the standard method and so it can short circuit the call to the
actual generic function. User code which wants real high method lookup
performance will end up having to do something similar to the extent it
wants to support this piece of the method lookup protocol. We will not
provide any mechanisms to make this easy.
As far as the interaction with `combined methods' goes I think its quite
simple. Make-method-call actually expands something like this:
(progn (make-method-call #<m1>))
(progn (apply-method-function #<GF> #<M1> #<FN> (method list) .args.))
The actual function (maybe called make-method-function) which converts
the effective method form into something else takes care doing this
expansion of make-method-call of course. But that function is not
documented needless to say.
I also don't think we should have a function like handler-for. I think
that is too implementation specific.
-------
∂15-Apr-88 1046 Common-Lisp-Object-System-mailer Comment on CLOS
Received: from RELAY.CS.NET by SAIL.Stanford.EDU with TCP; 15 Apr 88 10:46:35 PDT
Received: from relay2.cs.net by RELAY.CS.NET id an24019; 15 Apr 88 11:25 EDT
Received: from utokyo-relay by RELAY.CS.NET id ar20898; 15 Apr 88 11:14 EDT
Received: by ccut.cc.u-tokyo.junet (5.51/6.3Junet-1.0/CSNET-JUNET)
id AA20202; Fri, 15 Apr 88 13:30:41 JST
Received: by aoyama.cc.aoyama.junet (3.2/6.3Junet-1.0)
id AA17656; Fri, 15 Apr 88 13:13:54 JST
Date: Fri, 15 Apr 88 13:13:54 JST
From: Masayuki Ida <ida%aoyama.cc.aoyama.junet@UTOKYO-RELAY.CSNET>
Return-Path: <ida@aoyama.cc.aoyama.junet>
Message-Id: <8804150413.AA17656@aoyama.cc.aoyama.junet>
To: common-lisp-object-system@SAIL.STANFORD.EDU,
ida%aoyama.cc.aoyama.junet@UTOKYO-RELAY.CSNET
Subject: Comment on CLOS
I got a mail which is attached at the bottom from Mr. Ohkubo
who is chairing the subcommitte for OOPS under my Jeida
Common Lisp Committee.
My personal opinion is not included here.
But, I feel several of them are agreeable.
I will send my comment in a separate mail.
PLEASE INCLUDE MY NAME IN THE LIST AS "IDA%AOYAMA.JUNET@RELAY.CS.NET".
Thank you.
Masayuki Ida
-------------------------- The mail I got --------------------------------
From ohkubo@pfrad.pf.fujitsu.junet Thu Apr 14 15:32:01 1988
Date: Wed, 13 Apr 88 17:05:24 JST
Subject: Please forward this mail to CLOS mailing-list
Dear Prof. Ida,
Please forward this mail to CLOS mailing-list.
Thanks in advance.
ohkubo
-------------------------------------------------------------------------------
Here are some questions and problems about the CLOS draft. I hope this
will help to refine the CLOS specification.
--- ohkubo
(ohkubo%pfrad.pf.fujitsu.junet@uunet.uu.NET)
1. About the error signaled when next method doesn't exit.
The CLOS spec intends the user should check whether the next method exits
by next-method-p, but it will degrade the modularity, because the user
should concern about his method might have a method with the same name
which discriminate on the super class or combined with method combination.
In the system where multiple inheritance is supported, next method of
some method doesn't mean one unique method. There is a case where same
method have a next method in on case, and there isn't next method in another
case, depending on the context. (On the other hand, in Smalltalk 'super'
method can be decided statically). The method combination facility further
complicates the decision whether next method might be exit. This might
enforce the user should always use next-method-p.
To solve this problem, Object System should call a generic function named
such as 'no-next-method', when call-next-method is invoked but there isn't
such method, and the default method of 'no-next-method' should signal an
error. With this modification user can write 'no-next-method' which does
nothing or invokes error notifier. This mechanism is the same as
'no-applicable-method'.
2. Who and when remove a method defined on 'update-instance-structure'?
Updating instances with class redefinition is important, but the procedure
should be existed temporarily while only updating. With the current
specification, the method defined on 'update-instance-structure' will
become a garbage who will never be called again. Because the class specified
at its parameter-specializer is obsolete after redefining the class, but the
method will last until someone removes it. If user intends to remove the
'obsolete method', he can't have a confidence that the method is obsolete
and never be used agained. Because some implementation might postpone
updating instance until the object will actually be used.
My proposal with this problem, see 3.
3. CLOS doesn't support updating a slot structure.
Update-instance-structure gives chance to revise an instance structure while
redefining class, but it can't be used to revise a slot strucure. For
example, some slot now holding a list and the user find it can be an array
and want to convert slot structure of the existing instances for compacting
memory. In this case, class definition itself need not be changed, so
updating-instance-strucure doesn't be called. If the user redefines the
class with the same class description intentionally, update-instance-
structure can't get proper arguments, because slot name remaines unchanged.
To solve the problems stated at 2 and 3, CLOS should include 'all-instances'
with the same function as 'allInstances' of Smalltalk. I know this is
very difficult for some implementation. But 'all-instances' is very
convenient while maintaining objects in virtual image. It will not be
appropriate to demand 'all-instances' be implemented fast enough as other
lisp functions.
4. CLOS doesn't specify what will be happen when defining an ordinary function
or a macro which has the same name with the existing generic function.
5. When defining a generic function having the same name with the preexisting
ordinary function, current spec says it is error. Is it a proper definition?
In contrast to the case of defgeneric or defmethod, add-method includes the
ordinary function as a default method. What is this rationale? Might it be
rather proper to retain consistency?
6. 'delete-class' and 'delete-generic-function' should be defined.
It isn't easy and isn't clear to delete a class or a generic function as the
case of deleting a structure or a function for the user. It also depends
heavily on each implementation. CLOS should define user interface to
delete a class and a generic function, and also provide sufficient mechanism
for the programmer writing a programming environment.
7. Will it properly work when there are methods with the parameter specializers
whose meta classes are different in one generic function?
8. Introducing private slot.
In classical object systems such as Smalltalk or Flavors, there are methods
they have special semantics for a particular class. This is implied by each
method is belonged to some class. In the methods defined on this class or
its subclasses, instance variables defined in this class are freely
accessible. This makes it possible some slot, which only accessible in some
group of methods, doesn't need to define an accessor. But in CLOS, there
isn't a class which have special semantics for a method. CLOS should provide
the mechanism which allows to access a slot only in some group of methods.
In the current spec, someone want to read a slot and define reader then all
the people can read it.
9. At the first line of page 1-35 in CLOS draft, "Declaring Method Combination"
might be better than "Declarative Method Combinarion". Declarative method
combination means for some reader the demon method such as :before and :after
method, and procedural method combination means 'super', 'run-super', or
'call-next-method'.
-------------------------------------------------------------------------------
∂15-Apr-88 1345 Common-Lisp-Object-System-mailer CLOS comments
Received: from ti.com by SAIL.Stanford.EDU with TCP; 15 Apr 88 13:45:29 PDT
Received: by ti.com id AA14433; Fri, 15 Apr 88 15:43:22 CDT
Received: from Kelvin by tilde id AA27176; Fri, 15 Apr 88 15:44:53 CDT
Message-Id: <2786129024-9418538@Kelvin>
Sender: GRAY@Kelvin.csc.ti.com
Date: Fri, 15 Apr 88 15:43:44 CDT
From: David N Gray <Gray@DSG.csc.ti.com>
To: Common-lisp-object-system@sail.stanford.edu
Cc: Gray@DSG.csc.ti.com
Subject: CLOS comments
Comments on section 2 of the "Common Lisp Object System Specification"
(X3J13 document 88-002 dated March 1988):
Functionality comments:
-----------------------
DEFCLASS needs to permit a slot option of the form:
(:DOCUMENTATION doc-string)
Any implementation would be permitted to ignore this, but the
standard should recommend that the specified doc-string should become the
value to be returned by the DOCUMENTATION function for any reader methods
created for the slot by the :READER or :ACCESSOR options.
I recognize that an implementation is already permitted to support this as
an extension, but since the use of documentation should be encouraged
rather than made more difficult, I think it is unacceptable to require
users to write code that looks like this:
...
(:READER FOO)
#+(OR TI ...) ; implementations that I happen to know accept this
(:DOCUMENTATION "...")
...
when it is trivial for an implementation to just ignore the option if it
doesn't wish to support it.
It is not apparent why GENERIC-FUNCTION needs to be a special form instead
of a macro.
The CLOS standard should specify that implementations which support it
should include the symbol :CLOS in their *FEATURES* list.
Editorial comments:
-------------------
On page 2-8, the description "... of the form S or of the form S*" is a
little confusing because S is not defined.
I think it would be helpful if locally defined macros and functions (such
as CALL-METHOD and CALL-NEXT-METHOD) had a syntax line that said "Local
Macro" or "Local Function" instead of just "Macro" or "Function".
On page 2-25, third paragraph, the sentence "The slot name argument is a
symbol that can be used as a Common Lisp variable name." is confusing. It
seems to be saying that the name becomes defined such that it can be
accessed just like a variable (as in flavors), but this is only true
through the use of WITH-SLOTS, which is not mentioned here. Probably what
was intended was that the slot name must satisfy the same syntactic
requirements as a variable name, i.e. a symbol which is not a keyword,
nil, or t.
-- David Gray, Texas Instruments
∂19-Apr-88 1610 Common-Lisp-Object-System-mailer Re: dependent update protocol
Received: from WILMA.BBN.COM ([128.89.1.216]) by SAIL.Stanford.EDU with TCP; 19 Apr 88 16:10:39 PDT
Received: by WILMA.BBN.COM id aa23673; 19 Apr 88 19:00 EDT
To: Gregor.pa@xerox.com
cc: common-lisp-object-system@sail.stanford.edu
Subject: Re: dependent update protocol
In-reply-to: Your message of Mon, 11 Apr 88 11:38:00 -0700.
<880411113858.6.GREGOR@SPIFF.parc.xerox.com>
Date: Tue, 19 Apr 88 15:26:26 -0400
From: kanderso@WILMA.BBN.COM
Although i didn't like the way you cons/cdr'ed things on reinitargs, i
guess it is safe as long as everyone uses it that way.
I can't seem to find a better way.
k
∂20-Apr-88 0953 Common-Lisp-Object-System-mailer DEADLINE for finishing 1 and 2
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 20 Apr 88 09:53:25 PDT
Received: from Semillon.ms by ArpaGateway.ms ; 20 APR 88 09:46:18 PDT
Date: Wed, 20 Apr 88 09:46 PDT
From: Gregor.pa@Xerox.COM
Subject: DEADLINE for finishing 1 and 2
To: common-lisp-object-system@sail.stanford.edu
Fcc: BD:>Gregor>mail>outgoing-mail-2.text.newest
Message-ID: <19880420164612.1.GREGOR@PORTNOY.parc.xerox.com>
Line-fold: no
Its getting about time to send out chapter 2 to X3J13. I think we
should try to send it as close to the end of the month as we can in
order for them to have plenty of time to read it.
It seems that the issue of re-working the initialization mechanism must
be done before then. I haven't seen any messages on this in a while.
Does that mean that we are going for some version of Danny's last
proposal? Does anyone have other proposals or comments?
-------
∂20-Apr-88 1008 Common-Lisp-Object-System-mailer dependent update protocol
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 20 Apr 88 10:06:59 PDT
Received: from Semillon.ms by ArpaGateway.ms ; 20 APR 88 10:01:25 PDT
Date: Wed, 20 Apr 88 10:00 PDT
From: Gregor.pa@Xerox.COM
Subject: dependent update protocol
To: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
cc: common-lisp-object-system@SAIL.STANFORD.EDU
Fcc: BD:>Gregor>mail>outgoing-mail-2.text.newest
In-Reply-To: <19880411195010.7.MOON@EUPHRATES.SCRC.Symbolics.COM>
Message-ID: <19880420170053.2.GREGOR@PORTNOY.parc.xerox.com>
Line-fold: no
Date: Mon, 11 Apr 88 15:50 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Actually your example shows that it's not really true that the format
of the information is unspecified. What is specified is that it is a list
with one element for each interested class, in most-specific-first order.
What is unspecified is the format of the list elements.
No, the format of the information itself is unspecified. Any given
layer could choose to encapsulate the next layer of information any way
it wants. Its true that the example I used builds a list, but some
level might just as well use an array.
It's usually better not to try to pass extra args through a mapping
function; instead the function being mapped can be a closure that knows
the extra args. This is more flexible, and is how all eight functions
in CLtL whose names start with "map" work. Thus I would make
map-dependents take only two arguments.
Good point. We will make this change.
(defmethod reinitialize-instance :around
((object updatable-object-mixin) &rest reinitargs)
(let ((before (apply #'before-reinitialization object reinitargs)))
(call-next-method)
(let ((update-args
(apply #'after-reinitialization object before reinitargs)))
(map-dependents object #'update-dependent object update-args))))
I don't see how this can work if reinitialize-instance changes the set
of dependents. The map-dependents will map over the new dependents, and
any old dependents that were removed will never be updated. Maybe you
can say that remove-dependent, or by convention each caller of it, calls
update-dependent or a variant of it on the dependent being removed.
However, I suspect that is not flexible enough. I know some of our
analogues to this have to start by collecting all the dependents into a
table that is independent of the dependency structure. I don't have an
answer here; I think more thought is required.
As Danny said, the method on reinitialize-instance itself wan't intended
to change the set of dependents. We could get that functionality easily
enough by having the :around method collect all the dependents ahead of
time as you mentioned. We will make this change.
If that's true I would prefer to have the style (collecting lists of values
returned by each interested method, and taking them apart again) be enforced
by method combination, instead of leaving it up to each programmer to get
it right.
Also, since the style you propose depends on three methods for three different
generic functions to be kept in sync, and does something unpredictable without
necessarily signalling an error if one of the methods is left out, it doesn't
seem very robust. I would prefer to see either a more abstract data structure
than a list, so that leaving out a method (or forgetting to call cdr) for one
class would not damage the data seen by other class's methods, or else to use
one generic function instead of three, so that all the code for one class would
be in a single place and hence less likely to be out of sync. In the latter
case, this generic function would be called multiple times and one of its
arguments would indicate whether state was being collected or
distributed.
I think these might be good ideas. Unfortunately, in the abscence of a
specific proposal for how to make this work I think we are going to make
only the two changes described in this message. We don't have the time
to figure out how to incorporate this comment given that what we have
will clearly work.
-------
∂20-Apr-88 1205 Common-Lisp-Object-System-mailer dependent update protocol
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 20 Apr 88 12:04:56 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 385908; Wed 20-Apr-88 14:21:41 EDT
Date: Wed, 20 Apr 88 14:21 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: dependent update protocol
To: Gregor.pa@Xerox.COM
cc: common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: <19880420170053.2.GREGOR@PORTNOY.parc.xerox.com>
Message-ID: <19880420182131.2.MOON@EUPHRATES.SCRC.Symbolics.COM>
Line-fold: No
Date: Wed, 20 Apr 88 10:00 PDT
From: Gregor.pa@Xerox.COM
Date: Mon, 11 Apr 88 15:50 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Also, since the style you propose depends on three methods for three different
generic functions to be kept in sync, and does something unpredictable without
necessarily signalling an error if one of the methods is left out, it doesn't
seem very robust. I would prefer to see either a more abstract data structure
than a list, so that leaving out a method (or forgetting to call cdr) for one
class would not damage the data seen by other class's methods, or else to use
one generic function instead of three, so that all the code for one class would
be in a single place and hence less likely to be out of sync. In the latter
case, this generic function would be called multiple times and one of its
arguments would indicate whether state was being collected or
distributed.
I think these might be good ideas. Unfortunately, in the abscence of a
specific proposal for how to make this work I think we are going to make
only the two changes described in this message. We don't have the time
to figure out how to incorporate this comment given that what we have
will clearly work.
And will clearly break if misused. Here's an idea: someone, I forget who,
suggested using a property list as the state that's passed around, instead
of letting each class's methods decide how they are going to encapsulate
the next class's state. If you do that, then methods getting out of sync
can cause any damage. The only way for one class to damage another is for
both to use the same property name. But the property names can be class
objects.
Let me know if this is not a specific enough proposal and I'll somehow,
I don't know how, find the time to write it up more clearly.
∂20-Apr-88 1206 Common-Lisp-Object-System-mailer dependent update protocol
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 20 Apr 88 12:05:20 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 385909; Wed 20-Apr-88 14:22:33 EDT
Date: Wed, 20 Apr 88 14:22 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: dependent update protocol
To: Gregor.pa@Xerox.COM
cc: common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: <19880420170053.2.GREGOR@PORTNOY.parc.xerox.com>
Supersedes: <19880420182131.2.MOON@EUPHRATES.SCRC.Symbolics.COM>
Comments: Crucial word "not" was missing. Sorry about that.
Message-ID: <19880420182225.3.MOON@EUPHRATES.SCRC.Symbolics.COM>
Line-fold: No
Date: Wed, 20 Apr 88 10:00 PDT
From: Gregor.pa@Xerox.COM
Date: Mon, 11 Apr 88 15:50 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Also, since the style you propose depends on three methods for three different
generic functions to be kept in sync, and does something unpredictable without
necessarily signalling an error if one of the methods is left out, it doesn't
seem very robust. I would prefer to see either a more abstract data structure
than a list, so that leaving out a method (or forgetting to call cdr) for one
class would not damage the data seen by other class's methods, or else to use
one generic function instead of three, so that all the code for one class would
be in a single place and hence less likely to be out of sync. In the latter
case, this generic function would be called multiple times and one of its
arguments would indicate whether state was being collected or
distributed.
I think these might be good ideas. Unfortunately, in the abscence of a
specific proposal for how to make this work I think we are going to make
only the two changes described in this message. We don't have the time
to figure out how to incorporate this comment given that what we have
will clearly work.
And will clearly break if misused. Here's an idea: someone, I forget
who, suggested using a property list as the state that's passed around,
instead of letting each class's methods decide how they are going to
encapsulate the next class's state. If you do that, then methods
getting out of sync cannot cause any damage. The only way for one class
to damage another would be for both to use the same property name, but
the property names can be class objects.
Let me know if this is not a specific enough proposal and I'll somehow,
I don't know how, find the time to write it up more clearly.
∂20-Apr-88 1452 Common-Lisp-Object-System-mailer dependent update protocol
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 20 Apr 88 14:52:24 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 20 APR 88 14:43:36 PDT
Date: Wed, 20 Apr 88 14:40 PDT
From: Gregor.pa@Xerox.COM
Subject: dependent update protocol
To: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>, Danny Bobrow
<Bobrow.pa@Xerox.COM>, kanderso@WILMA.BBN.COM
cc: common-lisp-object-system@SAIL.STANFORD.EDU
Fcc: BD:>Gregor>mail>outgoing-mail-2.text.newest
In-Reply-To: <880411113858.6.GREGOR@SPIFF.parc.xerox.com>,
<19880411195010.7.MOON@EUPHRATES.SCRC.Symbolics.COM>,
<880414-114257-18564@Xerox>,
<19880420170053.2.GREGOR@PORTNOY.parc.xerox.com>,
<19880420182225.3.MOON@EUPHRATES.SCRC.Symbolics.COM>,
The message of 19 Apr 88 12:26 PDT from kanderso@WILMA.BBN.COM
Message-ID: <19880420214048.1.GREGOR@PORTNOY.parc.xerox.com>
Line-fold: no
Date: Wed, 20 Apr 88 14:22 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
And will clearly break if misused. Here's an idea: someone, I forget
who, suggested using a property list as the state that's passed around,
instead of letting each class's methods decide how they are going to
encapsulate the next class's state. If you do that, then methods
getting out of sync cannot cause any damage. The only way for one class
to damage another would be for both to use the same property name, but
the property names can be class objects.
Incorporating this with what we had previously is fairly easy. It looks
something like this:
- there is a separate mixin for the dependents stuff, that mixin
is used by standard-class to do dependents updating. Users can
use it in their code to particpate in that dependent updating
protocol.
- There is a mechanism for allowing the modified object to pass
information describing the modification to all the dependents.
This mechanism is designed to allow subclassing to work. That
is, a given class (say standard-class) may use this mechanism to
pass information to its dependents. The format of the
information is a plist which each class in the chain can put
information into and take it back out of. Each class is
expected to put one entry in the PLIST, and should use the
actual class object as the key. This will prevent name
conflicts in the plist. The format of the individual entries
in the plist is completely unspecified. It is undefined what
happens if system information in the plist is modified or
removed. It is undefined what system information will be in
the plist.
CLOS supports a general mechanism for registering dependents of objects,
and updating those objects on change. It does this through the medium
of a mixin class, updatable-object-mixin, that supports updating of
dependents. A dependent of an object O1 is any object that may need to
be updated when O1 changes. An object becomes a dependent only by
explicitly registering itself as one. The dependent registering
protocol allows redundant registering of dependents; this means that
code which wants an object to be registered as a dependent of an object
should always do so. It should never depend on the particular
implementation to do so since specific implementations may use the
dependent updating protocol in different ways.
Some examples of the use are:
1) A screen view of an object (perhaps a class) needs to update itself
when the object (class definition) changes. To do this it registers
itself as a dependent of that object, whenever the object changes it
will update all its dependents.
2) A subclass of a class wants to recompute its class precedence list
when the class changes its direct superclasses. The subclass
registers itself as a dependent of the class, whenever the class
changes, the subclass is updated and can recompute its class
precedence list.
3) Some set of objects needs to be updated when a class changes. This
can be handled in one of two ways, all the objects can be registered
as dependents, or a single object can be created which encapsulates
all the other objects. The single `large' object can be registered
as a dependent.
(defclass updatable-object-mixin () ())
This class supports two protocols, registration and updating of
dependents. The registration protocol is comprised of the generic
functions add-dependent, remove-dependent, and map-dependents. The
updating protocol is comprised of methods on reinitialize-instance, and
the generic functions before-reinitialization, after-reinitialization
and update-dependent.
The Registration Protocol
\Defmeth add-dependent ((object updatable-object-mixin) new-dependent)
adds new-dependent as a new dependent of object. Does nothing if
new-dependent is already a dependent of object.
\Defmeth remove-dependent ((object updatable-object-mixin) dependent)
removes dependent as one of the dependents of object. Does nothing
if dependent is not already one of the dependents of object.
\Defmeth map-dependents ((instance updatable-object-mixin) function)
For all dependents of instance, applies function to the dependent.
The Updating Protocol
The updating protocol has two parts. The first part is an :around
method on reinitialize-instance which causes all the dependents of an
object to be updated whenever the object is reinitialized. This part of
the protocol also provides a mechanism which allows the object to pass
information to its dependents describing the change effected by
reinitializing the object. This mechanism is provided by having the
:around method on reinitialize-instance call the generic-function
before-reinitialization before the reinitialization, and the
generic-function after-reinitializing after the reinitialization. The
value returned by after-reinitialization is passed in the call to
update-dependent on each of the dependents.
[We are still actively soliciting suggestions for better names for
before-reinitialization and after-reinitialization.]
(defmethod reinitialize-instance :around
((object updatable-object-mixin) &rest reinitargs)
(let ((dependents ()))
;; Collect all the dependents ahead of time. The fact that
;; a list is used here means nothing. The fact that this
;; code preserves the order that map-dependents does it in
;; is important though.
(map-dependents object #'(lambda (x) (push x dependents)))
(setq dependents (reverse dependents))
;; Collect the before-reinitialization information. This will be
;; a plist.
(let ((before (apply #'before-reinitialization object reinitargs)))
(call-next-method)
;; Collect the after-reinitialization information. This will
;; also be plist.
(let ((after
(apply #'after-reinitialization object before reinitargs)))
(dolist (dep dependents)
(update-dependent object dep after))))))
The updatable-object-mixin provides implementations of
before-reinitialization, after-reinitialization, and update-dependent.
(defmethod before-reinitialization ((object updateable-object) &rest ignore)
())
(defmethod after-reinitialization ((object updateable-object)
before-reinitialization
&rest ignore)
())
(defmethod update-dependent ((dependent updateable-object)
(object updateable-object)
after-reinitialization)
())
Example:
This example shows how this protocol might be used. In particular, it
demonstrates the proper style of using the plist to pass information
around. The standard methods on before-reinitialization,
after-reinitialization and update-dependent are there to support this.
Suppose that a specific kind of metaclass wants to propagate special
information when used as a submetaclass of itself.
(defclass my-class (standard-class) ())
(defmethod before-reinitialization ((c my-class) &rest reinitiargs)
(let ((plist (call-next-method)))
(setf (getf plist (class-named 'my-class))
(<compute-the-magic-info>))
plist))
(defmethod after-reinitialization ((c my-class) before &rest reinitargs)
(let ((plist (call-next-method)))
(setf (getf plist (class-named 'my-class))
(<compute-the-magic-info>))))
(defmethod update-dependent ((dependent my-class)
(object my-class)
plist)
(let ((magic-info (getf plist (class-named 'my-class))))
(<do something with the magic info>)
(call-next-method)
(<maybe do something else with magic info>)))
-------
∂20-Apr-88 1615 Common-Lisp-Object-System-mailer Re: dependent update protocol
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 20 Apr 88 16:14:39 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 20 APR 88 16:09:12 PDT
Date: 20 Apr 88 16:08 PDT
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Re: dependent update protocol
In-reply-to: Gregor.pa's message of Wed, 20 Apr 88 14:40 PDT
To: Gregor.pa@Xerox.COM
cc:Moon@STONY-BROOK.SCRC.Symbolics.COM, Bobrow.pa@Xerox.COM,
kanderso@WILMA.BBN.COM, common-lisp-object-system@SAIL.STANFORD.EDU
Message-ID: <880420-160912-1489@Xerox>
I had originally proposed the property list scheme. I claimed that properties
would have advertised names, and advertised meanings. Interference of property
names would then be intentional, or a bug.
For example, for class updating I had specified that the resulting arguments
delivered to all dependents would be a property list containing three flags,
:supers-changed :slots-changed and :options-changed. Alternatively, the
specification might be that there were simply one flag, :changed, with value an
integer between 0 and 7 whose bits indicated the same changes. These flags could
be used by all dependents of the class to determine if they were interested in
the change. For example, the class itself would be interested in any change, a
subclass might ignore options, and a class browser would ignore :slots-changed
and :options-changed.
I want to write
(defmethod update-dependent
((dependent class-browser-element)
(class standard-class) &key supers-changed &allow-other-keys T)
(when supers-changed (recompute-my-browser-display dependent)))
The point I am making is that we cannot encapsulate the information that is to
be passed to dependents if we do not know the full set of dependents. If the
properties are not advertised as part of the protocol for a particular class, I
don't see how a new kind of dependent could get any clue about what had happened
to the instance.
On the other hand, there is absolutely no such restriction on the information
that before-reinitialization passes to after reinitialization, and I think in
that case the class-keyed property list might be OK.
∂20-Apr-88 1744 Common-Lisp-Object-System-mailer DEADLINE for finishing 1 and 2
Received: from labrea.Stanford.EDU by SAIL.Stanford.EDU with TCP; 20 Apr 88 17:43:53 PDT
Received: by labrea.Stanford.EDU; Wed, 20 Apr 88 16:43:17 PST
Received: from bhopal.lucid.com by edsel id AA14363g; Wed, 20 Apr 88 16:38:19 PDT
Received: by bhopal id AA12537g; Wed, 20 Apr 88 16:39:58 PDT
Date: Wed, 20 Apr 88 16:39:58 PDT
From: Jon L White <edsel!jonl@labrea.Stanford.EDU>
Message-Id: <8804202339.AA12537@bhopal.lucid.com>
To: Gregor.pa@xerox.com
Cc: common-lisp-object-system@sail.stanford.edu
In-Reply-To: Gregor.pa@Xerox.COM's message of Wed, 20 Apr 88 09:46 PDT <19880420164612.1.GREGOR@PORTNOY.parc.xerox.com>
Subject: DEADLINE for finishing 1 and 2
re: It seems that the issue of re-working the initialization mechanism must
be done before then. I haven't seen any messages on this in a while.
There have been a flurry of messages on (re)initialization, and I'm not
sure if it all settled down. As a reminder, at the last X3J13 meeting,
I brought up the matter of the similarity of the initialization protocols
and the re-initialization ones; someone (probably you or moon) suggested
that this issue would be dealt with in the mails, and that I should hold
my question until something more concrete appears. I think I'm still
waiting?
-- JonL --
∂20-Apr-88 1855 Common-Lisp-Object-System-mailer DEADLINE for finishing 1 and 2
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 20 Apr 88 18:54:57 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 386222; Wed 20-Apr-88 21:06:26 EDT
Date: Wed, 20 Apr 88 21:06 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: DEADLINE for finishing 1 and 2
To: Jon L White <edsel!jonl@labrea.Stanford.EDU>
cc: Gregor.pa@xerox.com, common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: <8804202339.AA12537@bhopal.lucid.com>
Message-ID: <19880421010607.3.MOON@EUPHRATES.SCRC.Symbolics.COM>
Line-fold: No
Date: Wed, 20 Apr 88 16:39:58 PDT
From: Jon L White <edsel!jonl@labrea.Stanford.EDU>
There have been a flurry of messages on (re)initialization, and I'm not
sure if it all settled down. As a reminder, at the last X3J13 meeting,
I brought up the matter of the similarity of the initialization protocols
and the re-initialization ones; someone (probably you or moon) suggested
that this issue would be dealt with in the mails, and that I should hold
my question until something more concrete appears. I think I'm still
waiting?
I think your question is exactly what we've been working on.
∂20-Apr-88 1949 Common-Lisp-Object-System-mailer Re: method-lambda and apply-method-lambda
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 20 Apr 88 19:48:55 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 386276; Wed 20-Apr-88 22:48:47 EDT
Date: Wed, 20 Apr 88 22:48 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: method-lambda and apply-method-lambda
To: common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: <880414150957.6.GREGOR@SPIFF.parc.xerox.com>
Message-ID: <19880421024826.8.MOON@EUPHRATES.SCRC.Symbolics.COM>
I agree with what Gregor said in the referenced message, except
for two small points noted below. Does any of this affect chapters
1 and 2? It would only affect CALL-METHOD, and I don't think it does,
so we can defer completing the last details of this for a few days.
Date: Thu, 14 Apr 88 15:09 PDT
From: Gregor.pa@Xerox.COM
make-method-function (generic-function method lambda-list body)
This has to take a macroexpand-environment also. This sometimes needs
to do code analysis of the body, at least for some method calling
sequences, and it is impossible to do correct code analysis of a piece
of code without having a macroexpand-environment.
apply-method-function generic-function method function info &rest args
This is also a generic function. It tends to be specialied on its first
two arguments as well. For the case where generic-function and method
are both standard, the info argument is a list of the next methods.
I still believe that the representation of the info used for
call-next-method has to be abstract. CLOS should not dictate that it is
represented as a list. Note that I am not only saying that user-defined
method calling sequences should be able to use any representation they
want; I am also saying that CLOS should not dictate what representation
the standard method calling sequence uses. See my message of 8 April
for the two functions that have to be added to the system to abstract
this.
∂20-Apr-88 1954 Common-Lisp-Object-System-mailer comments on CLOS draft 88-2
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 20 Apr 88 19:53:53 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 386282; Wed 20-Apr-88 22:53:50 EDT
Date: Wed, 20 Apr 88 22:53 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: comments on CLOS draft 88-2
To: common-lisp-object-system@SAIL.STANFORD.EDU
References: The message of 8 Apr 88 14:13 EDT from "mike@gold-hill.com any day now" <mike%acorn@oak.lcs.mit.edu>,
<8804132019.AA00841@mist.UUCP>,
<8804150413.AA17656@aoyama.cc.aoyama.junet>,
<2786129024-9418538@Kelvin>
Message-ID: <19880421025339.9.MOON@EUPHRATES.SCRC.Symbolics.COM>
The four referenced messages are ones I've been saving as official comments
received that we need to address. We cannot complete the revisions of
chapters 1 and 2 without addressing these comments. I'm not sure we
completed discussing Pierson's comments, and I haven't seen any discussion
at all of Ohkubo's and Gray's comments. Did I miss some mail?
I'm willing to spend a little time putting together a summary of these
comments and a draft of the committee response, but I probably can't do
it until early next week.
∂20-Apr-88 2012 Common-Lisp-Object-System-mailer dependent update protocol
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 20 Apr 88 20:11:58 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 386293; Wed 20-Apr-88 23:11:52 EDT
Date: Wed, 20 Apr 88 23:11 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: dependent update protocol
To: common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: <19880420214048.1.GREGOR@PORTNOY.parc.xerox.com>,
<880420-160912-1489@Xerox>
Message-ID: <19880421031140.0.MOON@EUPHRATES.SCRC.Symbolics.COM>
The combination of these two messages (sent respectively by Gregor
and by Danny earlier today) looks like the right thing, although I
suppose I ought to take the time to think about it harder before
agreeing with it for sure.
The only problem I noticed is the usual bug with mixins that use
call-next-method instead of method combination. Because of the
way the default methods for before-reinitialization and
after-reinitialization are defined, and because there is no
ordering constraint that forces updateable-object to be least
specific in the class precedence list, it is possible for these
default methods accidentally to shadow real methods for those
generic functions. The best way to fix this is to use method
combination to ensure that all the methods are called and the
value returned by each method is passed in as the plist argument
to the next method. This might also help fix the bug where your
second example after-reinitialization method forgot to return
its result. A worse way to fix it would be to put in a bunch
of (and (next-method-p) (call-next-method)) forms.
∂20-Apr-88 2025 Common-Lisp-Object-System-mailer Re: Reinitialization
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 20 Apr 88 20:25:35 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 386302; Wed 20-Apr-88 23:25:30 EDT
Date: Wed, 20 Apr 88 23:25 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: Reinitialization
To: Common-Lisp-Object-System@SAIL.STANFORD.EDU
In-Reply-To: <880413-111606-16288@Xerox>
Message-ID: <19880421032519.1.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: 13 Apr 88 11:15 PDT
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
(6) Why do the four updating functions have such inconsistent
interfaces?....
so the real issue is why don't class-changed and
update-instance-structure take similar arguments?
We decided that there was no reasonable way to specify what it meant to keep
around a copy of an obsolete-class and its methods, and therefore we had to use
the list descriptions of the old instance.
On the other hand, for class-changed, the methods and classes are current. Hence
it is reasonable to leave in the users hands the problem of keeping the method
for class-changed current.
Oh, right.
Suppose that instead of its present arguments, update-instance-structure
took an old-instance and a new-instance, where the old-instance was of
an old-class that was a direct subclass of the class being redefined.
old-instance and old-class have dynamic extent. Suppose further that
old-class has no methods of its own, so exactly the same methods are
applicable to old-instance as are applicable to new-instance (barring
bizarre use of methods on individuals). If we do this, then in the
rho/theta/x/y example, you can't use accessor methods to get the old
information, just as you can't use accessor methods now. The difference
is that an update-instance-structure method would use slot-value to
get the old slot values, and would use normal chapter 3 facilities to
find out what slots were added and removed, instead of getting that
information in an idiosyncratic way.
I think a change like that would make the language a little more
consistent. However, I don't feel strongly about it, as even with
that change there would still be no shortage of minor inconsistencies.
∂20-Apr-88 2052 Common-Lisp-Object-System-mailer Re: Reinitialization
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 20 Apr 88 20:52:18 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 386318; Wed 20-Apr-88 23:52:07 EDT
Date: Wed, 20 Apr 88 23:51 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: Reinitialization
To: Common-Lisp-Object-System@SAIL.STANFORD.EDU
In-Reply-To: <880413-111606-16288@Xerox>
Message-ID: <19880421035154.2.MOON@EUPHRATES.SCRC.Symbolics.COM>
This message comments on the proposed revamping of the ch1 object
creation protocol in support of ch3.
Date: 13 Apr 88 11:15 PDT
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
The four updating functions are:
initialize-new-instance instance &rest initialization-arguments
reinitialize-instance instance &rest initialization-arguments
update-instance-structure instance added-slots discarded-slots property-list
&rest initialization-arguments
update-instance-with-new-class previous current
&rest initialization-arguments
This suggests renaming update-instance-structure to
update-instance-with-redefined-class. With that change all five
names look consistent and fairly clear as to their meanings.
These all call:
initialize-instance instance slots-for-initform
&rest initialization-arguments
The value of slots-for-initform can be a list of slot-names (possibly nil) or T,
which is equivalent to specifying all slots of the instance. For each slot on
the list, if it is uninitialized, and it has an initfunction, it is initialized
with the value of applying the initfunction to NIL.
What value does each of each of the updating functions pass to
initialize-intance for this argument.
The call from initialize-new-instance passes T of course.
The call from reinitialize-instance passes NIL
The call from update-instance-structure passes added-slots
The call from update-instance-with-new-class passes new-slots
Gregor and I previously argued that reinitialize-instance should try to
reinitialize all the slots that were unititialized. We claimed that this would
allow a specialized reinitialization method to call slot-makunbound on just
those slots wanted reinitialized. However, achieving this is still easy. The
specialized method still makes these slots unbound, and passes along the list of
slots that have been made unbound to initialize-instance.
All four pass the initialization-arguments to initialize-instance.
The call to update-instance-structure from the system of course passes NIL as
the initialization-arguments. So does the call to
update-instance-with-new-class. However, an :around method on either of these
latter can compute some interesting initialization-arguments and do a
call-next-method.
As an example of the use, consider the following around method for
update-instance-structure for point the above example:
(defmethod update-instance-structure :around ((p point) ...
;;push :x and :y on the initarg list and call-next-method
)
That only works if you change your method
(defmethod initialize-instance :after ((p point)) &key :x :y)
;; if x and y are provided, use (setf point-x) (setf point-y)
;; to compute the appropriate values for rho and theta
)
to be an initialize-new-instance method instead of an
initialize-instance method, and give it an ignored 2nd argument. It
seems likely that if you made this error, many users will make it too,
especially since the two names are so similar. I don't have any
suggestions I like for how to fix this.
Then the answers you propose to my seven issues are:
(1) How much should be shared among the four updating functions?
The (new) initialize-instance generic function, thus as much or
as little as you want.
(2) What should be shared among the four updating functions? There are
actually three different things:
(a) the code to fill slots from initialization arguments
(b) the code to fill slots from values of initialization forms
(c) user-defined methods
All three, but under complete control through arguments.
(3) We've discussed several clever/kludgey ways to tweak the shared code.
Do none of them.
(4) A subtle semantic change to class-changed and update-instance-structure
Don't do it.
(5) Do we really need four different updating functions?
Yes.
(6) Why do the four updating functions have such inconsistent interfaces?
Because any alternative we could think of created more problems than
it solved, e.g. tempting the user to invoke methods that won't work.
(7) What are good names for these five functions?
See above.
I'm happy with this. Let's do it.
Let's see, what are the actual changes to chapters 1 and 2?
Rename initialize-instance to initialize-new-instance.
Rename update-instance-structure to update-instance-with-redefined-class
(if you like my proposed name) and change its arguments.
Rename class-changed to update-instance-with-new-class
and change its arguments.
Add new functions reinitialize-instance and initialize-instance.
Adjust the procedural description of make-instance accordingly.
Change all places that talk about filling slots to say it's done by
the default primary method for (the new) initialize-instance.
Add explanations of how the default primary methods for the
four updating functions call initialize-instance, where it now
says how they fill slots on their own.
check-initargs has to be called from four different places now,
as there are four updating functions that have initargs arguments.
I think the best way is to give check-initargs another argument,
which is a list of generic functions. An initarg is acceptable if
it's a slot-filling initarg or if any of the generic functions in
the list accepts it. make-instance would pass
(list #'allocate-instance #'initialize-instance #'initialize-new-instance).
reinitialize-instance would pass
(list #'reinitialize-instance #'initialize-new-instance).
The only problem with this is that each of these takes idiosyncratic
arguments, which check-initargs has to take into account when computing
the applicable methods. Is there a better idea?
I think there is a little more technical fleshing out to be done before
this is reduced to purely editorial work, but it looks plausible.
Do any of the other committee members have an opinion on this? Are we
going overboard on generality, or is this a good change that makes the
language more consistent and hence easier to understand?
∂21-Apr-88 0707 Common-Lisp-Object-System-mailer some comments on CLOS
Received: from RELAY.CS.NET by SAIL.Stanford.EDU with TCP; 21 Apr 88 07:06:58 PDT
Received: from relay2.cs.net by RELAY.CS.NET id ab16910; 21 Apr 88 8:34 EDT
Received: from utokyo-relay by RELAY.CS.NET id ad06511; 21 Apr 88 7:46 EDT
Received: by ccut.cc.u-tokyo.junet (5.51/6.3Junet-1.0/CSNET-JUNET)
id AA04555; Thu, 21 Apr 88 20:02:23 JST
Received: by aoyama.cc.aoyama.junet (3.2/6.3Junet-1.0)
id AA07837; Thu, 21 Apr 88 19:32:30 JST
Date: Thu, 21 Apr 88 19:32:30 JST
From: Masayuki Ida <ida%aoyama.cc.aoyama.junet@UTOKYO-RELAY.CSNET>
Return-Path: <ida@aoyama.cc.aoyama.junet>
Message-Id: <8804211032.AA07837@aoyama.cc.aoyama.junet>
To: common-lisp-object-system@SAIL.STANFORD.EDU,
ida%aoyama.cc.aoyama.junet@UTOKYO-RELAY.CSNET
Subject: some comments on CLOS
Comments on CLOS ch1 and ch2.
(since I have been on this list
from two day ago, so I do not know
the current context.)
1. explanation around the mixture of defmethod and defun.
I could not find the specification on the mixture of
defmethod and defun with the same name.
is it error ? is it allowed in what sense?
2. for user convenience, explicit interface of
'make-specializable' in the former version is
better than the current way for doing the same
thing using 'user-added-method' or something.
3. Removal of a class and a method.
how user can remove one method ?
how user can remove a class ?
4. Enumeration in the individual method.
(defmethod foo ((x (eql A)))
...)
(defmethod foo ((x (eql B)))
...)
I have an experience to write
methods which have several sigular
points, and whose bodies are same.
I feel happy if a syntax like,
(defmethod foo ((x (member A B C D)))
...)
which shares the same body for the enumerated
individuals will be in the specificaton.
typos
5. 2-79 symbol-macrolet examples
;;; not (let 'foo (let (('foo 'bar)) 'foo)).
===>
;;; not (list 'foo (let (('foo 'bar)) 'foo)).
↑↑↑↑
Ambiguous
6. 2-8 line 9
Osub1 | ... | Osubn
and line 14
.... for some 1 <= k <= n, ...
'n' is ambiguous to the 'n' of line 13.
====>
line 9
Osub1 | ... | OsubN
and line 14
... for some 1 <= k <= N, ...
replacing small 'n' to large 'N'.
Comment
7. 1-19 to 1-21 Integrating Types and Classes
Fig 1-1.
I prefer 'sequence first rule'.
For instance,
the class precedence list of 'null' should be
(null list symbol sequence t)
or
(null list sequence symbol t)
rather than
(null symbol list sequence t) which
is on Fig 1-1.
How are the discussions on the issue ?
(defmethod foo ((x list))
...)
(defmethod foo ((x symbol))
...)
(foo nil) ?
I feel we cannot absolutely define
the precedence among them.
meta object protocol will solve this problem ?
8. 1-21
pathname and stream should at least be
defined to correspond to classes
independent from the context of 1-21.
(since several file handling are OK for
pathnames and streams)
say,
(defmethod device-analysis ((x pathname))
...)
(defmethod device-analysis ((x stream))
...)
-------
Masayuki Ida
∂21-Apr-88 0902 Common-Lisp-Object-System-mailer Sun Opposition To Chapter 3 Hereby Tendered
Received: from Sun.COM by SAIL.Stanford.EDU with TCP; 21 Apr 88 09:01:53 PDT
Received: from snail.sun.com by Sun.COM (4.0/SMI-4.0)
id AA01289; Thu, 21 Apr 88 08:59:54 PDT
Received: from suntana.sun.com by snail.sun.com (4.0/SMI-3.2)
id AA19379; Thu, 21 Apr 88 08:58:55 PDT
Received: from localhost by suntana.sun.com (3.2/SMI-3.2)
id AA02282; Thu, 21 Apr 88 08:52:35 PDT
Message-Id: <8804211552.AA02282@suntana.sun.com>
To: common-lisp-object-system@SAIL.STANFORD.EDU
Subject: Sun Opposition To Chapter 3 Hereby Tendered
Date: Thu, 21 Apr 88 08:52:33 -0700
From: kempf@Sun.COM
I hereby withdraw my support from the current and any future drafts
of Chapter 3, and tender Sun's opposition, unless substantial changes
are made. The purpose of CLOS is to provide a standard for object-oriented
programming in Common Lisp. While the design specified in Chapters 1 & 2
occasionally required features to be added which current object-oriented
languages do not have, the rationale behind these features and the effects on
implementation were understood to a large degree. I do not feel that is
the case with Chapter 3. There are many issues involved in supporting
metaobject programming which are not understood. I feel that the
current design effort is making the wrong choices in certain areas without
understanding the consequences. Solidifying these choices into a standard
runs the risk of hindering further developments.
Should the issue of Chapter 3 come to a vote before the full committee,
I will recommend that Sun vote against it. I will continue to support
Chapters 1 & 2 wholeheartly, since I believe the language specified
therein offers application programmers the best alternative among the current
object-oriented languages for flexible and efficient applications development.
jak
∂21-Apr-88 0920 Common-Lisp-Object-System-mailer Re: dependent update protocol
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 21 Apr 88 09:20:13 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 21 APR 88 09:17:14 PDT
Date: 21 Apr 88 09:16 PDT
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Re: dependent update protocol
In-reply-to: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>'s message of
Wed, 20 Apr 88 23:11 EDT
To: Moon@STONY-BROOK.SCRC.Symbolics.COM
cc: common-lisp-object-system@SAIL.STANFORD.EDU
Message-ID: <880421-091714-2738@Xerox>
Because of the way the default methods for
before-reinitialization and after-reinitialization are defined, and
because there is no ordering constraint that forces
updateable-object to be least specific in the class precedence
list, it is possible for these default methods accidentally to
shadow real methods for those generic functions. The best way to
fix this is to use method combination to ensure that all the
methods are called and the value returned by each method is passed
in as the plist argument to the next method.
I think it would be a good idea to use method combination, but I don't
understand how. Are you suggesting a different method combination type which
has this property. If so, what is its definition. If it uses standard method
combination and before methods, what is the sample code that avoids the bug
(does one smash the plist???).
danny
∂21-Apr-88 0920 Common-Lisp-Object-System-mailer Re: dependent update protocol
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 21 Apr 88 09:20:18 PDT
Received: from Semillon.ms by ArpaGateway.ms ; 21 APR 88 09:18:16 PDT
Date: Thu, 21 Apr 88 09:18 PDT
From: Gregor.pa@Xerox.COM
Subject: Re: dependent update protocol
To: Danny Bobrow <Bobrow.pa@Xerox.COM>
cc: Moon@STONY-BROOK.SCRC.Symbolics.COM, kanderso@WILMA.BBN.COM,
common-lisp-object-system@SAIL.STANFORD.EDU
Fcc: BD:>Gregor>mail>outgoing-mail-2.text.newest
In-Reply-To: <880420-160912-1489@Xerox>
Message-ID: <19880421161804.4.GREGOR@PORTNOY.parc.xerox.com>
Line-fold: no
Date: 20 Apr 88 16:08 PDT
From: Danny Bobrow <Bobrow.pa>
Danny's message prompted me to realize that there was a minor ommission
in the protocol. Specifically, the updated class should be passing the
actual reinitialization arguments to the update-dependent generic
function.
I think the way to think of this is as a mechanism which enables
objects, when they are updated, to pass special information to their
priviledged dependees describing how they were changed. Unpriveledged
dependees receive no special information, they only receive the
reinitialization arguments which caused the update.
So for example, when a class is updated, any of its dependents can see
the reinitialization arguments which caused the change. From those
reinitialization arguments the dependents can infer what they will about
how the class changed. But, a specific class of class (a metaclass) may
provide some sort of special information to its priviledged dependents.
This might include things like a bit saying whether or not the order of
the class's slots changed or something. Some metaclass may choose to
document the format and meaning of this information, but standard-class
does not do so.
This means that to write the kind of code you suggest you could do the
following:
(defmethod update-dependent ((class standard-class)
(dependent class-browser-element)
reinitargs
plist)
(when (getf reinitargs :direct-superclasses)
;; The supers may have changed. Check our local cache
;; to see if they actually have.
...))
You don't have access to the information in the plist because it is
implementation dependent, but you do have free access to the reinitargs.
The distinction between priviledged and unpriveledged information is
made clear by which plist the information is in.
-------
∂25-Apr-88 1223 Common-Lisp-Object-System-mailer Re: Reinitialization
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 25 Apr 88 12:20:47 PDT
Received: from Semillon.ms by ArpaGateway.ms ; 25 APR 88 11:39:28 PDT
Date: Mon, 25 Apr 88 11:26 PDT
From: Gregor.pa@Xerox.COM
Subject: Re: Reinitialization
To: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
cc: Common-Lisp-Object-System@SAIL.STANFORD.EDU
Fcc: BD:>Gregor>mail>outgoing-mail-2.text.newest
In-Reply-To: <19880421035154.2.MOON@EUPHRATES.SCRC.Symbolics.COM>
Message-ID: <19880425182606.0.GREGOR@PORTNOY.parc.xerox.com>
Line-fold: no
Date: Wed, 20 Apr 88 23:51 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
I think there is a little more technical fleshing out to be done before
this is reduced to purely editorial work, but it looks plausible.
Do any of the other committee members have an opinion on this? Are we
going overboard on generality, or is this a good change that makes the
language more consistent and hence easier to understand?
I believe we should go ahead and do this. It is clearly an improvement
to chapter 1+2, and should be treated as such.
How should this be handled? Dick and Linda, do you want to take a stab
at incorporating this? I assume the minor editorial comments from Kathy
Chapman have already be incorporated.
How should we handle the other comments? I am willing to take half of
them and draft replies. Dave, would you be willing to draft replies to
the rest? For any that we have problems on, we can get help from the
rest of the list. Then we can put them all together and send it out with
the
-------
∂25-Apr-88 1616 Common-Lisp-Object-System-mailer subcommittee meeting
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 25 Apr 88 16:15:56 PDT
Received: from Semillon.ms by ArpaGateway.ms ; 25 APR 88 16:07:25 PDT
Date: Mon, 25 Apr 88 16:05 PDT
From: Gregor.pa@Xerox.COM
Subject: subcommittee meeting
To: common-lisp-object-system@sail.stanford.edu
Fcc: BD:>Gregor>mail>outgoing-mail-2.text.newest
Message-ID: <19880425230532.1.GREGOR@PORTNOY.parc.xerox.com>
Line-fold: no
In Danny's absence, I propose that we plan to meet all day Tuesday.
If nobody disagrees, I will assume that Dick took care of letting Jan
know about this.
-------
∂25-Apr-88 1700 Common-Lisp-Object-System-mailer reinitialization etc
To: common-lisp-object-system@SAIL.Stanford.EDU
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>
I have been silent because I have a particularly deadly version of
the flu. When I read Danny's message and Moon's clarifications of
reinitialization, I wasn't sure I understood the implications, so
I'm not sure how well I can do incorporating them.
I have done Chapmans's chapter 1 comments, and LGD is doing her chapter 2
ones. There are some comments by Sonya that need incorporation.
I've had to cancel some trips and things to accommodate my flu, so I
nervous about my ability to do a lot of work in the next week or so.
-rpg-
∂26-Apr-88 0956 Common-Lisp-Object-System-mailer Re: Reinitialization
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 26 Apr 88 09:52:28 PDT
Received: from JUNCO.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via INTERNET with SMTP id 391724; 26 Apr 88 12:52:32 EDT
Date: Tue, 26 Apr 88 12:51 EDT
From: Sonya E. Keene <skeene@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: Reinitialization
To: Moon@STONY-BROOK.SCRC.Symbolics.COM
cc: Common-Lisp-Object-System@SAIL.STANFORD.EDU
In-Reply-To: <19880421035154.2.MOON@EUPHRATES.SCRC.Symbolics.COM>
Message-ID: <19880426165158.1.SKEENE@JUNCO.SCRC.Symbolics.COM>
This message suggests some better names.
I'm willing to take a shot at putting this new material into Chapters 1
and 2.
Date: Wed, 20 Apr 88 23:51 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
This message comments on the proposed revamping of the ch1 object
creation protocol in support of ch3.
Date: 13 Apr 88 11:15 PDT
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
The four updating functions are:
initialize-new-instance instance &rest initialization-arguments
reinitialize-instance instance &rest initialization-arguments
update-instance-structure instance added-slots discarded-slots property-list
&rest initialization-arguments
update-instance-with-new-class previous current
&rest initialization-arguments
This suggests renaming update-instance-structure to
update-instance-with-redefined-class. With that change all five
names look consistent and fairly clear as to their meanings.
Suggestion 1 (to be superseded below by Suggestion 2):
How about these two names instead of "-with-new-class" and
"-with-redefined-class"? "With" seems overloaded, and this use of it
is inconsistent with "with-open-file", etc. Also, "new class" is
overloaded; it means both "newly-created class" and "different class".
update-instance-structure-for-different-class
update-instance-structure-for-redefined-class
Suggestion 2 (this one I prefer):
Let's get rid of the "-structure" from these names, and use the
following names:
update-instance-for-different-class
update-instance-for-redefined-class
Why? Well, take a look at pages 1-15 and 1-16. The chapter on
Redefining Classes explains that this is a two-step process. Step 1 is
"Modifying the Structure of Instances", which is done by an un-named
process. Step 2 is called "Initializing Newly-added Local Slots",
which is done by the generic function currently called
update-instance-structure. Thus update-instance-structure has nothing
to do with updating the instance structure, because it is called AFTER
the instance structure has been updated.
Just plain update-instance-for-different-class and
update-instance-for-redefined-class seem to describe what they actually
do, where "update-instance-" is shorthand for "update the appropriate
slots of the instance to have the correct values".
∂26-Apr-88 1139 Common-Lisp-Object-System-mailer Re: Reinitialization
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 26 Apr 88 11:39:09 PDT
Received: from Semillon.ms by ArpaGateway.ms ; 26 APR 88 11:31:48 PDT
Date: Tue, 26 Apr 88 11:29 PDT
From: Gregor.pa@Xerox.COM
Subject: Re: Reinitialization
To: Sonya E. Keene <skeene@STONY-BROOK.SCRC.Symbolics.COM>
cc: Moon@STONY-BROOK.SCRC.Symbolics.COM,
Common-Lisp-Object-System@SAIL.STANFORD.EDU
Fcc: BD:>Gregor>mail>outgoing-mail-2.text.newest
In-Reply-To: <19880426165158.1.SKEENE@JUNCO.SCRC.Symbolics.COM>
Message-ID: <19880426182922.4.GREGOR@PORTNOY.parc.xerox.com>
Line-fold: no
I like these names just fine.
-------
∂26-Apr-88 1332 Common-Lisp-Object-System-mailer Re: Reinitialization
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 26 Apr 88 13:31:04 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 392001; Tue 26-Apr-88 16:30:50 EDT
Date: Tue, 26 Apr 88 16:30 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: Reinitialization
To: Common-Lisp-Object-System@SAIL.STANFORD.EDU
In-Reply-To: <19880421035154.2.MOON@EUPHRATES.SCRC.Symbolics.COM>
Message-ID: <19880426203020.4.MOON@EUPHRATES.SCRC.Symbolics.COM>
This issue has not been addressed yet, I think.
Date: Wed, 20 Apr 88 23:51 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
check-initargs has to be called from four different places now,
as there are four updating functions that have initargs arguments.
I think the best way is to give check-initargs another argument,
which is a list of generic functions. An initarg is acceptable if
it's a slot-filling initarg or if any of the generic functions in
the list accepts it. make-instance would pass
(list #'allocate-instance #'initialize-instance #'initialize-new-instance).
reinitialize-instance would pass
(list #'reinitialize-instance #'initialize-new-instance).
The only problem with this is that each of these takes idiosyncratic
arguments, which check-initargs has to take into account when computing
the applicable methods. Is there a better idea?
The basic goal is that for each of the seven functions that take initargs
as arguments (make-instance, allocate-instance, initialize-new-instance,
reinitialize-instance, update-instance-for-redefined-class,
update-instance-for-different-class, and initialize-instance), the
keyword arguments accepted without error are the initargs for slot filling
and the initargs accepted by applicable methods for any generic function
that is going to see these initargs, and only those. I hope you can
understand that run-on sentence. Thus for example I can define
(defmethod initialize-instance :after ((i my-class) ignore &key moo) ...)
and now reinitialize-instance of my-class accepts :moo without my having
to say anything else.
The above idea for changing check-initargs isn't such a great one.
Other ideas: split check-initargs into seven functions for the seven
cases. Make allocate-instance, initialize-new-instance, and initialize-instance
never check their arguments, since they're only "supposed to be" called
from other functions that already checked the arguments, thus needing
only four versions of check-initargs (I don't like this idea). Give
check-initargs a flag argument which is the name of the function on
whose behalf it has been called. Invent some new way for generic functions
to communicate with each other and negotiate for who handles each initarg.
Any bright ideas?
∂26-Apr-88 1557 Common-Lisp-Object-System-mailer X3 subcommittee meeting in June
Received: from labrea.Stanford.EDU by SAIL.Stanford.EDU with TCP; 26 Apr 88 15:57:12 PDT
Received: by labrea.Stanford.EDU; Tue, 26 Apr 88 15:56:19 PDT
Received: from sunvalleymall.lucid.com by edsel id AA11062g; Tue, 26 Apr 88 14:32:31 PDT
Received: by sunvalleymall id AA16752g; Tue, 26 Apr 88 14:34:10 PDT
Date: Tue, 26 Apr 88 14:34:10 PDT
From: Jan Zubkoff <edsel!jlz@labrea.Stanford.EDU>
Message-Id: <8804262134.AA16752@sunvalleymall.lucid.com>
To: common-lisp-object-system@sail.stanford.edu
Cc: edsel!jlz@labrea.Stanford.EDU
Subject: X3 subcommittee meeting in June
We're set for 10:00am Tuesday, June 14 in the Bonaire meeting
room on the first floor of Symbolics. Symbolics has a secure
building and will wait for all of you to arrive before guiding
us to the room. We need to be out by 5:30 when they close.
---jan---
∂26-Apr-88 1846 Common-Lisp-Object-System-mailer dealing with 1+2 comments
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 26 Apr 88 18:46:08 PDT
Received: from Semillon.ms by ArpaGateway.ms ; 26 APR 88 18:39:47 PDT
Date: Tue, 26 Apr 88 18:37 PDT
From: Gregor.pa@Xerox.COM
Subject: dealing with 1+2 comments
To: common-lisp-object-system@sail.stanford.edu
Fcc: BD:>Gregor>mail>outgoing-mail-2.text.newest
Message-ID: <19880427013737.5.GREGOR@PORTNOY.parc.xerox.com>
Line-fold: no
I am getting ready to address the comments we have received on chapter 1
and 2. This message explains how I intend to proceed, what I am going
to do, and what I am going to ask others to do.
I am going to start by separating the comments into editorial comments
and technical comments. An editorial comment is one which is directed
at the text of the specification. These need to be addressed by
clarifying some part of the specification. This usually means adding a
small amount of text explaining a particular situation. A technical
comment is one which is directed at the actual design of CLOS. These
comments need to be addressed by either explaining why we choose to
leave CLOS as it is, or what change we made to address the comment and
why we made that change.
I will collect all the editorial comments that have been sent to the
mailing list into one message. I will send this message to the whole
list. I will ask someone else to volunteer to address these comments by
making the appropriate changes in the specification.
I will then take the technical comments and, with David's help, I will
come to a preliminary decision as to what our response should be. As
described above, the response may suggest that we make some change to
the design, or it may just be an explanation of why we chose to leave
things as they were. I will write up these preliminary responses and
send them to the entire mailing list.
At that point, everyone should comment on the appropriateness of the
responses David and I came up with. The usual round robin of messages
can be used to reach closure on this.
I will then rework the responses to conform to what we have decided. I
will let someone else volunteer to make the appropriate changes to the
specification.
The bad news is that we have less than two weeks to do this whole thing,
including reach closure on the open issues having to do with
reinitialization.
-------
∂26-Apr-88 1915 Common-Lisp-Object-System-mailer editorial comments
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 26 Apr 88 19:15:23 PDT
Received: from Semillon.ms by ArpaGateway.ms ; 26 APR 88 19:13:29 PDT
Date: Tue, 26 Apr 88 19:11 PDT
From: Gregor.pa@Xerox.COM
Subject: editorial comments
To: common-lisp-object-system@sail.stanford.edu
Fcc: BD:>Gregor>mail>outgoing-mail-2.text.newest
Message-ID: <19880427021133.6.GREGOR@PORTNOY.parc.xerox.com>
Line-fold: no
Here are the editorial comments I have culled from the messages we
received. After some of the comments I put my own opinion in brackets.
From: Dan L. Pierson <pierson%mist@multimax.ARPA>
Page 1-9, Add to the list of things provided by slot options and
class options:
o Specifying the legal data types of the slot contents.
(Of course, this can be found elsewhere in the document,
but my impression on reading this introductory list was
that for some reason you couldn't do this.)
Page 1-11, Paragraphs 3 and 7
Why are reader, writer, and with-slots *required* to be
implemented using SLOT-VALUE? I don't doubt that you have
a good reason, but it's not obvious to a relative novice.
[These must call slot value because the implementation of slot-value for
a particular class can be changed using the MOP. We don't want to go
into that at this point in the document, but perhaps a simple forward
reference would be appropriate.
Paragraphs 7 and 8
This implies that WITH-SLOTS can access slots without
accessors but WITH-ACCESSORS can't. This is reasonable
but should probably be made explicit. Some people may
feel that this makes WITH-SLOTS unsafe.
[Yes this needs to be made explicit.]
Page 1-26, Paragraph 2, Sentence 2
The following are my exact notes as I read this section:
What about methods in both old and new? Are they "added"?
If so, in what way is this definition different from
saying that the "contents" of the old generic function are
trashed and replaced by the new generic function? AHA!
Some methods could have been defined by DEFMETHOD, but the
wording is still confusing.
Paragraph 6, Sentence 3
The wording is a bit confusing.
Page 1-28, Paragraph 2, Sentence 4 and example line
Has this been submitted to cleanup? I don't recognize it.
[He is confused by the use of the expression "This proposal" to describe
the CLOS specification. That should be clarified somehow.]
Page 1.29, Paragraph 1
The wording implies that:
(EQUAL '(A (B C)) '((A B) C))
is T, which is certainly false. Note that cleanup is
entertaining proposal to flush EQUAL and EQUALP.
[Just change this to the lists of qualifiers are EQUAL?]
Page 1-32, At this point I made a note:
In general, this draft details the complex, general case
before the simpler, common special case. This *may* be
appropriate for a standards document but it certainly
isn't for a manual.
[Sonya already explained to him that this wasn't a manual. I will
include this criticism in the ones we respond to in written form so that
we can answer it for everyone.]
Page 2-27, Next to last paragraph
Can extension slot options appear more than once in a
single slot description (it appears reasonable, but it's
not clear from this whether it's legal).
[Make it clear that extension slot options can appear more than once.]
Last paragraph
The slot can also be accessed by WITH-SLOTS, since
WITH-SLOTS uses SLOT-VALUE.
[Sonya doesn't feel it is necessary to make this explicit.]
Page 2-35, Paragraphs 7 and 8
These paragraphs don't specify how to distinguish a
predicate from the first keyword option since they are
both distinguished by being symbols other than * (or NIL).
[The predicate is distinguished by position. Either it or the list of
qualifiers or () or * must be in the same position. Somehow the text
should make this clear.]
Date: Fri, 15 Apr 88 13:43 PDT
From: David N Gray <Gray@DSG.csc.ti.com>
On page 2-8, the description "... of the form S or of the form S*" is a
little confusing because S is not defined.
I think it would be helpful if locally defined macros and functions (such
as CALL-METHOD and CALL-NEXT-METHOD) had a syntax line that said "Local
Macro" or "Local Function" instead of just "Macro" or "Function".
[I think this is a good idea.]
On page 2-25, third paragraph, the sentence "The slot name argument is a
symbol that can be used as a Common Lisp variable name." is confusing. It
seems to be saying that the name becomes defined such that it can be
accessed just like a variable (as in flavors), but this is only true
through the use of WITH-SLOTS, which is not mentioned here. Probably what
was intended was that the slot name must satisfy the same syntactic
requirements as a variable name, i.e. a symbol which is not a keyword,
nil, or t.
Date: Wed, 13 Apr 88 10:32 PDT
From: Sonya E. Keene <skeene@STONY-BROOK.SCRC.Symbolics.COM>
The section "Determining the Class Precedence List" has examples where
defclass is used to define classes, and the CPL is computed from those
definitions. However, the CPLs shown don't include standard-object
(they do include t). We should really fix this.
The table in Figure 1-1 has two columns, labelled "Predefined Common
Lisp Type" and "Class Precedence List". The first column heading isn't
right; actually, it is correct, but it misses the point. They are
Common Lisp types, but the important thing is that CLOS has classes
corresponding to those types. I think that column heading should be
simply "Classes" or "Predefined Classes" (since "Classes Corresponding
to Common Lisp Types" is too long).
Also, the section "Standard Meta-objects" says "The class named
standard-object is an instance of the class standard-class and is a
superclass of every class that is an instance of standard-class except
itself." I believe that the MOP (p 3-10) contradicts this statement,
since the class structure-object is an instance of the class
standard-class, yet it doesn't have standard-object as a superclass.
[The draft of the MOP you were reading was wrong here. structure-object
is an instance of structure-class.]
Date: Thu, 21 Apr 88 19:32:30 JST
From: Masayuki Ida <ida%aoyama.cc.aoyama.junet@UTOKYO-RELAY.CSNET>
Comments on CLOS ch1 and ch2.
1. explanation around the mixture of defmethod and defun.
I could not find the specification on the mixture of
defmethod and defun with the same name.
is it error ? is it allowed in what sense?
[Somehow we need to make the following clear.
defun calls setf of symbol-fucntion, so defun totally wipes out what
used to be in the symbols `function cell'. If the symbol used to name a
function it now names a new function. If the symbol used to name a
generic function, that generic function is gone and the symbol now just
names the new function
defmethod calls ensure-generic-function which signals an error if the
symbol already names an ordinary function or macro.
Here is the state table, it might be a good idea to put this in the
document?
function macro generic function
----------------------------------------------
|
defun | fn is macro is generic function
| replaced replaced is replaced
|
defmacro | fn is macro is generic function
| replaced replaced is replaced
|
defmethod | error error method is added to
| signalled signalled generic function,
| existing method may
| be replaced
]
typos
5. 2-79 symbol-macrolet examples
;;; not (let 'foo (let (('foo 'bar)) 'foo)).
===>
;;; not (list 'foo (let (('foo 'bar)) 'foo)).
↑↑↑↑
Ambiguous
6. 2-8 line 9
Osub1 | ... | Osubn
and line 14
.... for some 1 <= k <= n, ...
'n' is ambiguous to the 'n' of line 13.
====>
line 9
Osub1 | ... | OsubN
and line 14
... for some 1 <= k <= N, ...
replacing small 'n' to large 'N'.
-------
∂26-Apr-88 2115 Common-Lisp-Object-System-mailer "Written Responses" to CLOS 88-002: SETF Functions
Received: from labrea.Stanford.EDU by SAIL.Stanford.EDU with TCP; 26 Apr 88 21:15:02 PDT
Received: by labrea.Stanford.EDU; Tue, 26 Apr 88 21:15:12 PDT
Received: from bhopal.lucid.com by edsel id AA12851g; Tue, 26 Apr 88 20:54:49 PDT
Received: by bhopal id AA03909g; Tue, 26 Apr 88 20:56:52 PDT
Date: Tue, 26 Apr 88 20:56:52 PDT
From: Jon L White <edsel!jonl@labrea.Stanford.EDU>
Message-Id: <8804270356.AA03909@bhopal.lucid.com>
To: common-lisp-object-system@sail.stanford.edu
Subject: "Written Responses" to CLOS 88-002: SETF Functions
"Introduction to Setf Functions" Belongs in CLtL, not CLOS
The title of this response says it all. How many times have we heard CLOS
subcommittee members invoke a shield against criticism by saying "CLOS can't
hope to fix Common Lisp's problems.". But the Setf Functions section does
exactly that!
More to the point, there is no need, now, to have this in the CLOS spec,
since it has already been tentatively approved by the Cleanup committee.
At worst, the CLOS spec may want to contain this exposition as a kind of
extended footnote, so that newer readers not familiar with the other X3J13
work will know what is going on.
-- JonL --
∂26-Apr-88 2131 Common-Lisp-Object-System-mailer "Written Responses" to CLOS 88-002: (Re)Initialization
Received: from labrea.Stanford.EDU by SAIL.Stanford.EDU with TCP; 26 Apr 88 21:31:43 PDT
Received: by labrea.Stanford.EDU; Tue, 26 Apr 88 21:31:48 PDT
Received: from bhopal.lucid.com by edsel id AA13049g; Tue, 26 Apr 88 21:25:02 PDT
Received: by bhopal id AA03975g; Tue, 26 Apr 88 21:27:04 PDT
Date: Tue, 26 Apr 88 21:27:04 PDT
From: Jon L White <edsel!jonl@labrea.Stanford.EDU>
Message-Id: <8804270427.AA03975@bhopal.lucid.com>
To: common-lisp-object-system@sail.stanford.edu
Subject: "Written Responses" to CLOS 88-002: (Re)Initialization
Strong Similarity between Initialization/Reinitialization
The strong similarity between the Initialization and Reinitialization
protocols makes me wonder why there need to be two. Couldn't more be
factored out into a single protocol? The state of the design circa
November 1987 was unacceptably confusing to me; the situation in CLOS
88-002 appears to be one of avoiding the problem. I am aware that
significant discussion has been taking place on the electronic mailing
list during March and April 1988, so I'm sure something will be done; I
just want to register a "Response" so that at least the situation will
not be the same as it was during the winter of 1987-88.
-- JonL --
∂26-Apr-88 2131 Common-Lisp-Object-System-mailer "Written Responses" to CLOS 88-002: SYMBOL-CLASS is poorly named
Received: from labrea.Stanford.EDU by SAIL.Stanford.EDU with TCP; 26 Apr 88 21:31:31 PDT
Received: by labrea.Stanford.EDU; Tue, 26 Apr 88 21:31:40 PDT
Received: from bhopal.lucid.com by edsel id AA13042g; Tue, 26 Apr 88 21:23:16 PDT
Received: by bhopal id AA03970g; Tue, 26 Apr 88 21:25:20 PDT
Date: Tue, 26 Apr 88 21:25:20 PDT
From: Jon L White <edsel!jonl@labrea.Stanford.EDU>
Message-Id: <8804270425.AA03970@bhopal.lucid.com>
To: common-lisp-object-system@sail.stanford.edu
Subject: "Written Responses" to CLOS 88-002: SYMBOL-CLASS is poorly named
SYMBOL-CLASS is poorly named
The close binding of classes to symbols as names is a poor choice; there
really is no analogy with the other CL constructs that are currently
closely bound in with symbols (i.e., the ones that have "slots" in
the symbol reserved for them). Thus the following functions should renamed
(or removed!):
symbol-class
cboundp
cmakunbound
A reasonable renaming for 'symbol-class' is 'class-named'; a reasonable
replacement for 'cboundp' is simply whether or not 'class-named' returns
non-nil; a reasonable replacement for 'cmakunbound' is simply
(setf (class-named <foo>) nil)
Current CL "slot" names for symbols are in fact defensible. Generally,
there are two grounds:
(1) every symbol has a SYMBOL-NAME component, and virtually every
symbol has a SYMBOL-PACKAGE component; thus for storage efficiency,
having a slot in the symbol structure is best.
(2) many symbols have either a symbol-function or symbol-value
component; but more importantly, these properties implement two
of the basic features of the Lisp programming lanugage syntax --
function-call to dynamically-linked functions and free-variable
access to dynamic bindings; thus for running-speed considerations,
these should be a "slot" (i.e., the access from a symbol to its
global function or its dynamic value must be very fast).
(*) SYMBOL-PLIST is the weakest case of the existing slots; probably
no one would grieve if it were not implemented as a slot (but rather
as, say, a hashtable lookup).
Some persons have pointed out that CLtL does not require actual "slots" --
and that a deep-bound implementation of Common Lisp would not, for example,
implement SYMBOL-VALUE as a slot access. But this is a red-herring, since
even in deep-bound implementations there is the need for "global value"
slot for exactly the same reasons. Furthermore, nearly every commercial
implementation does indeed implement these particular symbol properties
as "slots"; one must assume that these vendors have reasonable grounds
for doing so, such as the above-mentioned ones.
However, there is no need for a "slot" for classes. Rather, the tendency
now is to prepare for names which are not symbols -- i.e., the "Definition
Specs" proposal before X3J13 [but since only symbols can name functions
in program syntax, there still is no need for name-to-function mapping to
be fast except on symbols]. It makes perfectly good sense to be able to
name classes with non-symbol "definition specs", although I wouldn't suggest
that these non-symbol "specs" be permissible as parameter-specializer-names;
at worst this would limit such names to classes that are "built up" with
primitives lower than DEFMETHOD etc.
Instead of the paradigm SYMBOL-<foo>, there is similar use of the paradigm
<foo>-NAMED elsewhere. In Gregor's slides before the recent X3J13 meeting,
he actually used CLASS-NAMED in a place or two, proving that that is the
more "natural" name for this feature. In a preprint of the paper "An
Object-Oriented Database System to Support an Integrated Programming
Environment", by Dan Weinreb et. al. of Symbolics, the authors describe
a database system linked closely with CLOS. "Entities" in this database
scheme have a name (always a symbol); the example entities which have a NAME
slot all have an "inverse" name mapping function called "<foo>-NAMED". The
PERSON entity has a NAME slot -- presumably to be accessed as PERSON-NAME;
and it also has, explicitly, the inverse PERSON-NAMED. Similarly for
DEPARTMENT-NAME and DEPARTMENT-NAMED. This is independent evidence of a
widespread convention: for a category of named things <foo>, the
name-to-thing mapping should be called <foo>-NAMED.
One possible objection: a named object with components will frequently have
names assigned to the components by suffixing "-<component-name>" to the
object name. Thus CLASS-NAMED might be mistaken for the NAMED slot of
classes. I claim it will never be so mistaken, primarily because of the
wide-spread use of the protocol just described, and also because there is a
tendency *not* to give names to components that are parsable (in English) as
a word in the past tense. Thus NAME and FROB are good component names for
classes, but NAMED and FROBBED are not. It just doesn't happen. If someone
wanted, say, a REDEFINED slot, as a way of remembering whether or not the
class had ever been redefined, he _probably_ would call it REDEFINED-P.
Note also that in the database paper just cited, there is an entity
COURSE with a TITLE slot; and the inverse name mapping is, very
appropriately, called COURSES-ENTITLED -- the "past tense" protocol.
[I might even suggest this simple linguistic device is worth noting
somewhere as a "good style" note.]
Benefits:
(1) refrain from making the mistake of suggesting that symbols have
a "class" slot; reduce false cognates on names like SYMBOL-PACKAGE.
(2) remove artificial blocks to the use of non-symbol names.
(3) align with the common protocol of using "<foo>-named" as the mapping
from names to <foo>'s.
-- JonL --
∂27-Apr-88 1107 Common-Lisp-Object-System-mailer belated editorial comment
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 27 Apr 88 11:07:52 PDT
Received: from Semillon.ms by ArpaGateway.ms ; 27 APR 88 11:06:43 PDT
Date: Wed, 27 Apr 88 10:59 PDT
From: Gregor.pa@Xerox.COM
Subject: belated editorial comment
To: common-lisp-object-system@sail.stanford.edu
Fcc: BD:>Gregor>mail>outgoing-mail-2.text.newest
Included-msgs: <8804270356.AA03909@bhopal.lucid.com>,
The message of 26 Apr 88 20:56 PDT from
edsel!jonl@labrea.Stanford.EDU,
The message of 26 Apr 88 20:56 PDT from Jon L White
Message-ID: <19880427175914.4.GREGOR@PORTNOY.parc.xerox.com>
Line-fold: no
I believe that this one of jonl's belated messages should be dealt with
by putting a comment at the front of this section saying this is just a
summary of something the cleanup committee is already dealing with.
Either that or it should be removed entirely.
Date: Tue, 26 Apr 88 20:56 PDT
From: Jon L White <edsel!jonl@labrea.Stanford.EDU>
To: common-lisp-object-system@sail.stanford.edu
Subject: "Written Responses" to CLOS 88-002: SETF Functions
"Introduction to Setf Functions" Belongs in CLtL, not CLOS
The title of this response says it all. How many times have we heard CLOS
subcommittee members invoke a shield against criticism by saying "CLOS can't
hope to fix Common Lisp's problems.". But the Setf Functions section does
exactly that!
More to the point, there is no need, now, to have this in the CLOS spec,
since it has already been tentatively approved by the Cleanup committee.
At worst, the CLOS spec may want to contain this exposition as a kind of
extended footnote, so that newer readers not familiar with the other X3J13
work will know what is going on.
-- JonL --
-------
∂27-Apr-88 1126 Common-Lisp-Object-System-mailer belated editorial comment
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 27 Apr 88 11:26:17 PDT
Received: from JUNCO.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 392888; Wed 27-Apr-88 14:25:51 EDT
Date: Wed, 27 Apr 88 14:25 EDT
From: Sonya E. Keene <skeene@STONY-BROOK.SCRC.Symbolics.COM>
Subject: belated editorial comment
To: Gregor.pa@Xerox.COM
cc: common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: <19880427175914.4.GREGOR@PORTNOY.parc.xerox.com>,
<8804270356.AA03909@bhopal.lucid.com>,
Your message,
The message of 26 Apr 88 23:56 EDT from Jon L White
Message-ID: <19880427182516.5.SKEENE@JUNCO.SCRC.Symbolics.COM>
Line-fold: No
Date: Wed, 27 Apr 88 10:59 PDT
From: Gregor.pa@Xerox.COM
I believe that this one of jonl's belated messages should be dealt with
by putting a comment at the front of this section saying this is just a
summary of something the cleanup committee is already dealing with.
Either that or it should be removed entirely.
Until Common Lisp itself has a spec in which all of the Cleanup issues
are documented, I think it best to keep this section in the CLOS spec.
Date: Tue, 26 Apr 88 20:56 PDT
From: Jon L White <edsel!jonl@labrea.Stanford.EDU>
To: common-lisp-object-system@sail.stanford.edu
Subject: "Written Responses" to CLOS 88-002: SETF Functions
"Introduction to Setf Functions" Belongs in CLtL, not CLOS
The title of this response says it all. How many times have we heard CLOS
subcommittee members invoke a shield against criticism by saying "CLOS can't
hope to fix Common Lisp's problems.". But the Setf Functions section does
exactly that!
More to the point, there is no need, now, to have this in the CLOS spec,
since it has already been tentatively approved by the Cleanup committee.
At worst, the CLOS spec may want to contain this exposition as a kind of
extended footnote, so that newer readers not familiar with the other X3J13
work will know what is going on.
I believe the CLOS spec will have many readers who are not familiar with
the other X3J13 work that is going on.
-- JonL --
-------
∂27-Apr-88 1129 Common-Lisp-Object-System-mailer "Written Responses" to CLOS 88-002: SETF Functions
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 27 Apr 88 11:29:48 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via INTERNET with SMTP id 392897; 27 Apr 88 14:29:31 EDT
Date: Wed, 27 Apr 88 14:29 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: "Written Responses" to CLOS 88-002: SETF Functions
To: Jon L White <edsel!jonl@labrea.Stanford.EDU>
cc: common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: <8804270356.AA03909@bhopal.lucid.com>
Message-ID: <19880427182909.7.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Tue, 26 Apr 88 20:56:52 PDT
From: Jon L White <edsel!jonl@labrea.Stanford.EDU>
"Introduction to Setf Functions" Belongs in CLtL, not CLOS
....there is no need, now, to have this in the CLOS spec,
since it has already been tentatively approved by the Cleanup committee.
My notes from the March X3J13 meeting say that X3J13 failed to make a
decision on the setf functions issue, because it got tied up with a larger
issue of "function specs" that a different committee was going to work
on. Was a decision made late Thursday afternoon, after I left? I seem
to have lost my copy of the minutes of the meeting, or maybe they have
not been mailed out yet.
If X3J13 has adopted setf functions, I agree that the CLOS spec does not
need to discuss them. If X3J13 is still dithering, I think the writeup
should stay in the CLOS spec. If X3J13 has rejected setf functions, then
we have a problem.
∂27-Apr-88 1345 Common-Lisp-Object-System-mailer Re: "Written Responses" to CLOS 88-002: SYMBOL-CLASS is poorly named
Received: from Score.Stanford.EDU by SAIL.Stanford.EDU with TCP; 27 Apr 88 13:45:28 PDT
Received: from hplabs.HP.COM by SCORE.STANFORD.EDU with TCP; Wed 27 Apr 88 13:39:58-PDT
Received: from hplms2.HP.COM (hplms2) by hplabs.HP.COM with SMTP ; Wed, 27 Apr 88 12:44:44 PST
Received: from hplwhh.HPL.HP.COM (hplwhh.hpl.hp.com) by hplms2.HP.COM; Wed, 27 Apr 88 13:44:26 pdt
Received: from hplwhh by hplwhh.HPL.HP.COM; Wed, 27 Apr 88 13:42:59 pdt
To: Jon L White <edsel!jonl@labrea.Stanford.EDU>
Cc: common-lisp-object-system@sail.stanford.edu
Subject: Re: "Written Responses" to CLOS 88-002: SYMBOL-CLASS is poorly named
X-Mailer: mh6.5
In-Reply-To: Your message of Tue, 26 Apr 88 21:25:20 -0700.
<8804270425.AA03970@bhopal.lucid.com>
Date: Wed, 27 Apr 88 13:42:57 PDT
Message-Id: <7701.578176977@hplwhh>
From: Warren Harris <harris%hplwhh@hplabs.HP.COM>
SYMBOL-CLASS is poorly named
I've often thought this too, since there is no CLASS slot on symbol objects
(nor would I want there to be). Although you've given very good arguments
in favor of the alternative name CLASS-NAMED, you might also consider the
name FIND-CLASS. This would correpsond with other CL naming functions
like FIND-SYMBOL and FIND-PACKAGE. I would also then suggest renaming
GET-METHOD to FIND-METHOD to fit into this scheme.
∂27-Apr-88 1407 Common-Lisp-Object-System-mailer Editorial Comments and My Disposition of Them
To: common-lisp-object-system@SAIL.Stanford.EDU
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>
Here is a series of excerpts from Gregor's message and how I dealt with them:
From: Dan L. Pierson <pierson%mist@multimax.ARPA>
Page 1-9, Add to the list of things provided by slot options and
class options:
o Specifying the legal data types of the slot contents.
(Of course, this can be found elsewhere in the document,
but my impression on reading this introductory list was
that for some reason you couldn't do this.)
[RPG: ok]
Page 1-11, Paragraphs 3 and 7
Why are reader, writer, and with-slots *required* to be
implemented using SLOT-VALUE? I don't doubt that you have
a good reason, but it's not obvious to a relative novice.
[These must call slot value because the implementation of slot-value for
a particular class can be changed using the MOP. We don't want to go
into that at this point in the document, but perhaps a simple forward
reference would be appropriate.
Paragraphs 7 and 8
This implies that WITH-SLOTS can access slots without
accessors but WITH-ACCESSORS can't. This is reasonable
but should probably be made explicit. Some people may
feel that this makes WITH-SLOTS unsafe.
[Yes this needs to be made explicit.]
[RPG: ok]
Page 1-26, Paragraph 2, Sentence 2
The following are my exact notes as I read this section:
What about methods in both old and new? Are they "added"?
If so, in what way is this definition different from
saying that the "contents" of the old generic function are
trashed and replaced by the new generic function? AHA!
Some methods could have been defined by DEFMETHOD, but the
wording is still confusing.
[RPG: Maybe it is, but it is quite precise. I think it's ok.]
Paragraph 6, Sentence 3
The wording is a bit confusing.
[RPG: either I cannot find what he is talking about or else he is very
confused. The sentence he refers to simply lists the forms in a category
that was just defined.]
Page 1-28, Paragraph 2, Sentence 4 and example line
Has this been submitted to cleanup? I don't recognize it.
[He is confused by the use of the expression "This proposal" to describe
the CLOS specification. That should be clarified somehow.]
[RPG: ok]
Page 1.29, Paragraph 1
The wording implies that:
(EQUAL '(A (B C)) '((A B) C))
is T, which is certainly false. Note that cleanup is
entertaining proposal to flush EQUAL and EQUALP.
[Just change this to the lists of qualifiers are EQUAL?]
[RPG: The prose already states that we are dealing with lists of qualifiers
and not with anything resembling his point.]
Page 1-32, At this point I made a note:
In general, this draft details the complex, general case
before the simpler, common special case. This *may* be
appropriate for a standards document but it certainly
isn't for a manual.
[Sonya already explained to him that this wasn't a manual. I will
include this criticism in the ones we respond to in written form so that
we can answer it for everyone.]
Date: Wed, 13 Apr 88 10:32 PDT
From: Sonya E. Keene <skeene@STONY-BROOK.SCRC.Symbolics.COM>
The section "Determining the Class Precedence List" has examples where
defclass is used to define classes, and the CPL is computed from those
definitions. However, the CPLs shown don't include standard-object
(they do include t). We should really fix this.
[RPG: Fixed]
The table in Figure 1-1 has two columns, labelled "Predefined Common
Lisp Type" and "Class Precedence List". The first column heading isn't
right; actually, it is correct, but it misses the point. They are
Common Lisp types, but the important thing is that CLOS has classes
corresponding to those types. I think that column heading should be
simply "Classes" or "Predefined Classes" (since "Classes Corresponding
to Common Lisp Types" is too long).
[RPG: Fixed]
Also, the section "Standard Meta-objects" says "The class named
standard-object is an instance of the class standard-class and is a
superclass of every class that is an instance of standard-class except
itself." I believe that the MOP (p 3-10) contradicts this statement,
since the class structure-object is an instance of the class
standard-class, yet it doesn't have standard-object as a superclass.
[The draft of the MOP you were reading was wrong here. structure-object
is an instance of structure-class.]
[RPG: Clarified the wording.]
Date: Thu, 21 Apr 88 19:32:30 JST
From: Masayuki Ida <ida%aoyama.cc.aoyama.junet@UTOKYO-RELAY.CSNET>
Comments on CLOS ch1 and ch2.
1. explanation around the mixture of defmethod and defun.
I could not find the specification on the mixture of
defmethod and defun with the same name.
is it error ? is it allowed in what sense?
[Somehow we need to make the following clear.
defun calls setf of symbol-fucntion, so defun totally wipes out what
used to be in the symbols `function cell'. If the symbol used to name a
function it now names a new function. If the symbol used to name a
generic function, that generic function is gone and the symbol now just
names the new function
defmethod calls ensure-generic-function which signals an error if the
symbol already names an ordinary function or macro.
Here is the state table, it might be a good idea to put this in the
document?
function macro generic function
----------------------------------------------
|
defun | fn is macro is generic function
| replaced replaced is replaced
|
defmacro | fn is macro is generic function
| replaced replaced is replaced
|
defmethod | error error method is added to
| signalled signalled generic function,
| existing method may
| be replaced
]
[RPG: I think this is already clear. There is a section on naming
generic functions which states that generic functions are named
exactly as normal functions are. There are clear passages that state
that trying to add methods to non-generic functions cause errors to be
signaled. Trying to define a function on top of a generic function is
covered by the naming discussion. I think if we say anything more than
what is already said, we will be specifying CL more than CL is currently
specified. There is already no discussion of what the following does in CL
except for the function naming disucssion in CLtL:
(defun f ...)
(defun f ...)
For example, we don't know what this does either:
(defun f ...)
(defmacro f ...)
So, the best we can do is to state that the generic function names are
exactly like CL ones and leave as an implication that your implementation
will do to generic functions whatever it does to ordinary functions
under DEFUN and DEFMACRO.]
∂27-Apr-88 1712 Common-Lisp-Object-System-mailer Re: Reinitialization
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 27 Apr 88 17:12:00 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 27 APR 88 17:04:45 PDT
Date: 27 Apr 88 17:03 PDT
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Re: Reinitialization
In-reply-to: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>'s message of
Tue, 26 Apr 88 16:30 EDT
To: Moon@STONY-BROOK.SCRC.Symbolics.COM
cc: Common-Lisp-Object-System@SAIL.STANFORD.EDU
Message-ID: <880427-170445-6290@Xerox>
check-initargs has to be called from four different places
now, as there are four updating functions that have initargs
arguments. I think the best way is to give check-initargs
another argument, which is a list of generic functions. An
initarg is acceptable if it's a slot-filling initarg or if any
of the generic functions in the list accepts it. make-instance
would pass (list #'allocate-instance #'initialize-instance
#'initialize-new-instance). reinitialize-instance would pass
(list #'reinitialize-instance #'initialize-new-instance). The
only problem with this is that each of these takes
idiosyncratic arguments, which check-initargs has to take into
account when computing the applicable methods. Is there a
better idea?
The basic goal is that for each of the seven functions that
take initargs as arguments (make-instance, allocate-instance,
initialize-new-instance, reinitialize-instance,
update-instance-for-redefined-class,
update-instance-for-different-class, and initialize-instance), the
keyword arguments accepted without error are the initargs for slot
filling and the initargs accepted by applicable methods for any
generic function that is going to see these initargs, and only
those.
The following is an alternative that would be more generally useful. It
provides a more general form of the functionality described above. It will be
useful anytime keyword arguments are going to be combined and passed to multiple
generic functions.
The idea is to have a function that would check a set of keyword arguments
against those accepted by a set of methods. The set of methods would be the
methods from the supplied generic functions that are applicable to the supplied
arguments. In addition, it is possible to specify additional acceptable
keywords.
check-keyword-arguments arguments
generic-functions
&optional extra-allowed-keywords
make instance would call check-keyword-arguments this way
(defmethod make-instance ((class standard-class) &rest initargs)
(setq initargs (default-initargs class initargs))
(unless (check-keyword-arguments
(cons (class-prototype class) initargs)
(list #'allocate-instance
#'initialize-instance
#'initialize-new-instance)
(class-slot-initargs class))
(error "illegal initarg"))
.
.
.)
Clearly the first value returned by this function is T or NIL. There is some
question as to whether it should return other values saying which keyword
arguments were illegal, and what the total set of legal keyword arguments is.
∂27-Apr-88 1720 Common-Lisp-Object-System-mailer Re: Reinitialization
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 27 Apr 88 17:20:40 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 393344; Wed 27-Apr-88 20:20:35 EDT
Date: Wed, 27 Apr 88 20:20 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: Reinitialization
To: Danny Bobrow <Bobrow.pa@Xerox.COM>
cc: Common-Lisp-Object-System@SAIL.STANFORD.EDU
In-Reply-To: <880427-170445-6290@Xerox>
Message-ID: <19880428002009.9.MOON@EUPHRATES.SCRC.Symbolics.COM>
Line-fold: No
Date: 27 Apr 88 17:03 PDT
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
(unless (check-keyword-arguments
(cons (class-prototype class) initargs)
(list #'allocate-instance
#'initialize-instance
#'initialize-new-instance)
(class-slot-initargs class))
(error "illegal initarg"))
But this doesn't work because each one of allocate-instance,
initialize-instance, and initialize-new-instance takes slightly
different arguments.
∂28-Apr-88 0933 Common-Lisp-Object-System-mailer Re: Reinitialization
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 28 Apr 88 09:33:39 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 28 APR 88 09:32:23 PDT
Date: 28 Apr 88 09:32 PDT
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Re: Reinitialization
In-reply-to: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>'s message of
Wed, 27 Apr 88 20:20 EDT
To: Moon@STONY-BROOK.SCRC.Symbolics.COM
cc: Bobrow.pa@Xerox.COM, Common-Lisp-Object-System@SAIL.STANFORD.EDU
Message-ID: <880428-093223-7329@Xerox>
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
(unless (check-keyword-arguments
(cons (class-prototype class) initargs)
(list #'allocate-instance
#'initialize-instance
#'initialize-new-instance)
(class-slot-initargs class))
(error "illegal initarg"))
But this doesn't work because each one of allocate-instance,
initialize-instance, and initialize-new-instance takes slightly
different arguments.
Unfortuntately, right. I have two patches for this, since I think the idea is
good. Both patches have problems. Here are the alternative patches.
1) The difference in arguments is that #'initialize-instance takes a second
required argument, slots-using-initforms. Instead, make slots-using-initforms
be a keyword argument. This implies that callers of make-instance and
reinitialize-instance could specify which slots they wanted filled with a value
computed from initforms. I can think of some uses for this, but it may be
exposed at the wrong level. I don't consider this a strong argument (either
way).
2) Change the argument structure for check-keyword-arguments
check-keyword-arguments required-arguments
key-word-arguments
generic-functions
&optional extra-allowed-keywords
Make required arguments be a list that can select the appropriate methods from
each generic funcion. If the list is too short, consider it equivalent to being
filled out with enough nils to be of the right length.
---
In either case I envision the code for check-keyword-arguments to use
something like keywords-for-applicable-methods (I called this generic function
method-applicable-keywords in Chapter 3).
(defmethod keywords-for-applicable-methods
((g-fn standard-generic-function)
required-arguments)
;; find the list of applicable methods for
;; required arguments given
;; possibly filling out list of required arguments with nils
;; take the union of these keywords
)
However, there is a problem in using keywords-for-applicable-methods in
check-keyword-arguments. What value does it return if &rest or
&allow-other-keys appears in any method?
If we take Moon's suggestion of returning the symbol &allow-other-keys in this
case, then check-keyword-arguments cannnot use this value, since the default
methods for initialize-instance and allocate-instance have an &rest argument.
If we take my suggestion of including &allow-other-keys in the list of allowable
keyword arguments, then we suffer from what Moon calls the "untasteful but legal
use of &allow-other-keys as a keyword argument." Perhaps we could outlaw that
use as a keyword in CLOS. Perhaps we could use another key -- is either T or
NIL outlawed as a keyword?
In general, where one wants to provide a common set of keyword arguments to a
set of functions, all must accept the keywords of the other functions. We need
some mechanism for knowing the explicitly handled keywords. That was the intent
of my last suggestion.
Ideas? Comments?
∂28-Apr-88 0953 Common-Lisp-Object-System-mailer "Written Responses" to CLOS 88-002: SETF Functions
Received: from labrea.Stanford.EDU by SAIL.Stanford.EDU with TCP; 28 Apr 88 09:53:27 PDT
Received: by labrea.Stanford.EDU; Thu, 28 Apr 88 09:53:23 PDT
Received: from bhopal.lucid.com by edsel id AA00488g; Thu, 28 Apr 88 07:13:26 PDT
Received: by bhopal id AA00769g; Wed, 27 Apr 88 19:10:14 PDT
Date: Wed, 27 Apr 88 19:10:14 PDT
From: Jon L White <edsel!jonl@labrea.Stanford.EDU>
Message-Id: <8804280210.AA00769@bhopal.lucid.com>
To: Moon@stony-brook.scrc.symbolics.com
Cc: common-lisp-object-system@sail.stanford.edu
In-Reply-To: David A. Moon's message of Wed, 27 Apr 88 14:29 EDT <19880427182909.7.MOON@EUPHRATES.SCRC.Symbolics.COM>
Subject: "Written Responses" to CLOS 88-002: SETF Functions
re: If X3J13 has adopted setf functions, I agree that the CLOS spec does not
need to discuss them. If X3J13 is still dithering, I think the writeup
should stay in the CLOS spec. If X3J13 has rejected setf functions, then
we have a problem.
SETF functions foundered on issues having nothing to do with function specs.
I say, "foundered", not meaning that they were rejected, but that substantial
issues were raised (mostly by Sandra Loosemore), and the discussion didn't
come to completion by the end of the day.
You missed the "Definitions Specs" presentation; there seemed to be
unanimous approval for continuing that proposal. Even if there is
continuing objection/discussion (and I don't think there will be) to the
particulars of the "setf functions" semantics, there doesn't seem to be
objections to "function specs".
I believe that most of Sandra's objections were met by our collective
responses that day. For example, she wanted to know why their syntax
differed from that suggested by DEFSETF -- why the "new value" was the
first argument rather than the last. We replied that it is necessary to
be able to discriminate on the class of the "new value", and there is
no easy syntax for defining a method that discriminates on the last
argument rather than the first several.
However, under no circumstances can one justify leaving a "fix up" of
CL in the CLOS spec. At best, CLOS should have an appendix explaining
any non-standard assumptions about the CL language -- an appendix which
itself isn't an integral part of the spec, but only an aid for those
who are not yet familiar with other X3J13 activity.
-- JonL --
∂29-Apr-88 1417 Common-Lisp-Object-System-mailer type slot option
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 29 Apr 88 14:16:53 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 29 APR 88 14:15:25 PDT
Date: Fri, 29 Apr 88 14:15 PDT
From: Gregor.pa@Xerox.COM
Subject: type slot option
To: common-lisp-object-system@sail.stanford.edu
Fcc: BD:>Gregor>mail>outgoing-mail-2.text.newest
Message-ID: <19880429211514.2.GREGOR@PORTNOY.parc.xerox.com>
Line-fold: no
One of the comments we received attacked several problems with the :type
slot option. The complaint, which came from Dan Pierson, sees to be
that because the :type option is not enforced by automatically defined
accessors or slot-value, you can't count on it to protect a slot from
having the wrong type of value stored in it. It seems he is thinking of
the type option as a `semantic' feature, rather than an optional
compiler declaration.
Here are his comments:
Date: Wed, 13 Apr 88 13:19 PDT
From: Dan L. Pierson <pierson%mist@multimax.ARPA>
Comments on Chapters 1 and 2 of the CLOS Spec (Edition of 2/8/88)
Page 1-13, Paragraph 4
This paragraph appears self-contradictory. I think that
it means that portable code cannot depend on slot types
since:
(1) Some implementations may not provide type errors
(therefore reducing the value of slot types for
debugging), and
(2) Calls from outside the package may store incorrect
types (so even if your portable code is self-consistent
you could wind up with undetected type errors).
Let's say you're implementing a window system which has slots
WINDOW-WIDTH and WINDOW-HEIGHT. You define these slots to be of type
integer *and* ensure that your code never puts a non-integer in them.
You still have to explicitly check the type of the slot value every
time any code that you didn't write could have run because a user
program could have put a non-integer in the slot without getting an
error in some implementations.
Moon said:
Common Lisp defines errors with respect to a single program. Common
Lisp does not address the issue of how one program can protect itself
against language violations committed by another program running in the
same Lisp. I don't think this problem is specific to CLOS in any way.
I don't think it's CLOS's business to do anything about it. Of course
I'd like to see Common Lisp fixed to eliminate this problem, for example
by completely eliminating the concept of type declaration. However in
the real world that is not going to happen; historically programmers
have been eager to accept incorrect code for the sake of efficiency.
Gregor said:
This is a problem. The reason we are losing is that we are thinking of
this :type slot option as a compiler feature whereas some user might
think of it as a real semantic feature. There are several ways out:
- drop the :type slot option entirely
- say that writer methods will check the type, but setf of
slot-value might not
- say that everything which write into the slot will check
the type
- say that everything which write into the slot should check
the type
- leave things the way they are, but make it clear that it
is the job of the user code to enforce the type option.
Moon said:
You're right that :TYPE is a compiler optimization, not a semantic
feature. It's like the TYPE declaration in that respect. If slot
options had been defined in a syntactically consistent way (i.e.
enclosed in parentheses like class options) then the syntax of this
slot option could have been based on the syntax of DECLARE and just
possibly people would be less confused about what it means. I'm not
seriously proposing that; I'd rather eliminate the option, if we're
going to make such a large change.
What should we do about this?
-------
∂29-Apr-88 1425 Common-Lisp-Object-System-mailer documentation slot option
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 29 Apr 88 14:25:47 PDT
Received: from Semillon.ms by ArpaGateway.ms ; 29 APR 88 14:20:55 PDT
Date: Fri, 29 Apr 88 14:20 PDT
From: Gregor.pa@Xerox.COM
Subject: documentation slot option
To: common-lisp-object-system@sail.stanford.edu
Fcc: BD:>Gregor>mail>outgoing-mail-2.text.newest
Message-ID: <19880429212048.3.GREGOR@PORTNOY.parc.xerox.com>
Line-fold: no
One of the comments we received proposed a :documentation slot option.
This option would provide a documentation string for the automatically
generated :reader or :writer methods for the slot.
So:
(defclass foo ()
((x :reader foo-x
:documentation "the x slot stores the x position")))
would be equivalent to
(defclass foo ()
((x)))
(defmethod foo-x ((foo foo))
"the x slot stores the x position"
(slot-value foo 'x))
This is the actual comment we received:
Date: Fri, 15 Apr 88 13:43 PDT
From: David N Gray <Gray@DSG.csc.ti.com>
Functionality comments:
-----------------------
DEFCLASS needs to permit a slot option of the form:
(:DOCUMENTATION doc-string)
Any implementation would be permitted to ignore this, but the
standard should recommend that the specified doc-string should become the
value to be returned by the DOCUMENTATION function for any reader methods
created for the slot by the :READER or :ACCESSOR options.
I recognize that an implementation is already permitted to support this as
an extension, but since the use of documentation should be encouraged
rather than made more difficult, I think it is unacceptable to require
users to write code that looks like this:
...
(:READER FOO)
#+(OR TI ...) ; implementations that I happen to know accept this
(:DOCUMENTATION "...")
...
when it is trivial for an implementation to just ignore the option if it
doesn't wish to support it.
I am mildly opposed to this because I think documentation strings are a
joke. I am also mildy opposed because it isn't clear that the same
documentation string could be useful for all the automatically generated
methods for a slot.
It is well defined though, so we could go ahead and do it.
What do others think?
-------
∂29-Apr-88 1430 Common-Lisp-Object-System-mailer generic-function special form
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 29 Apr 88 14:30:01 PDT
Received: from Semillon.ms by ArpaGateway.ms ; 29 APR 88 14:25:54 PDT
Date: Fri, 29 Apr 88 14:25 PDT
From: Gregor.pa@Xerox.COM
Subject: generic-function special form
To: common-lisp-object-system@sail.stanford.edu
Fcc: BD:>Gregor>mail>outgoing-mail-2.text.newest
Message-ID: <19880429212530.4.GREGOR@PORTNOY.parc.xerox.com>
Line-fold: no
One of the comments we received was:
Date: Fri, 15 Apr 88 13:43 PDT
From: David N Gray <Gray@DSG.csc.ti.com>
It is not apparent why GENERIC-FUNCTION needs to be a special form
instead of a macro.
Gregor said:
Because Common Lisp doesn't have lambda macros.
Moon said:
No, that's wrong, because GENERIC-FUNCTION is not something that can be
used inside the FUNCTION special form. In other words, GENERIC-FUNCTION
evaluates, it doesn't efunctuate. As far as I can see GENERIC-FUNCTION
could be a macro that expands into MAKE-INSTANCE <generic-function-class>
and a bunch of initargs including some that are forms that construct methods.
I think Gray is right on this one and it's a mistake in the document.
We should check with RPG, who proposed this.
Gregor said:
I am surprised to here that generic-function cannot be used inside the
function special form. It doesn't say that in the documentation, and
since the method bodies are supplied as forms, I think this must
efunctuate. It must capture the lexical scope it was used in or else
what is it worth?
What do others think?
-------
∂29-Apr-88 1436 Common-Lisp-Object-System-mailer symbol-class is bad name
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 29 Apr 88 14:36:14 PDT
Received: from Semillon.ms by ArpaGateway.ms ; 29 APR 88 14:36:08 PDT
Date: Fri, 29 Apr 88 14:35 PDT
From: Gregor.pa@Xerox.COM
Subject: symbol-class is bad name
To: common-lisp-object-system@sail.stanford.edu
Fcc: BD:>Gregor>mail>outgoing-mail-2.text.newest
Message-ID: <19880429213546.6.GREGOR@PORTNOY.parc.xerox.com>
Line-fold: no
One of the comments we received complained that symbol-class was poorly
named. It went on to suggest that cboundp and cmakunbound should be
removed from the language.
The full text of the comment was:
Date: Tue, 26 Apr 88 21:25:20 PDT
From: Jon L White <edsel!jonl@labrea.Stanford.EDU>
SYMBOL-CLASS is poorly named
The close binding of classes to symbols as names is a poor choice; there
really is no analogy with the other CL constructs that are currently
closely bound in with symbols (i.e., the ones that have "slots" in
the symbol reserved for them). Thus the following functions should renamed
(or removed!):
symbol-class
cboundp
cmakunbound
A reasonable renaming for 'symbol-class' is 'class-named'; a reasonable
replacement for 'cboundp' is simply whether or not 'class-named' returns
non-nil; a reasonable replacement for 'cmakunbound' is simply
(setf (class-named <foo>) nil)
Current CL "slot" names for symbols are in fact defensible. Generally,
there are two grounds:
(1) every symbol has a SYMBOL-NAME component, and virtually every
symbol has a SYMBOL-PACKAGE component; thus for storage efficiency,
having a slot in the symbol structure is best.
(2) many symbols have either a symbol-function or symbol-value
component; but more importantly, these properties implement two
of the basic features of the Lisp programming lanugage syntax --
function-call to dynamically-linked functions and free-variable
access to dynamic bindings; thus for running-speed considerations,
these should be a "slot" (i.e., the access from a symbol to its
global function or its dynamic value must be very fast).
(*) SYMBOL-PLIST is the weakest case of the existing slots; probably
no one would grieve if it were not implemented as a slot (but rather
as, say, a hashtable lookup).
Some persons have pointed out that CLtL does not require actual "slots" --
and that a deep-bound implementation of Common Lisp would not, for example,
implement SYMBOL-VALUE as a slot access. But this is a red-herring, since
even in deep-bound implementations there is the need for "global value"
slot for exactly the same reasons. Furthermore, nearly every commercial
implementation does indeed implement these particular symbol properties
as "slots"; one must assume that these vendors have reasonable grounds
for doing so, such as the above-mentioned ones.
However, there is no need for a "slot" for classes. Rather, the tendency
now is to prepare for names which are not symbols -- i.e., the "Definition
Specs" proposal before X3J13 [but since only symbols can name functions
in program syntax, there still is no need for name-to-function mapping to
be fast except on symbols]. It makes perfectly good sense to be able to
name classes with non-symbol "definition specs", although I wouldn't suggest
that these non-symbol "specs" be permissible as parameter-specializer-names;
at worst this would limit such names to classes that are "built up" with
primitives lower than DEFMETHOD etc.
Instead of the paradigm SYMBOL-<foo>, there is similar use of the paradigm
<foo>-NAMED elsewhere. In Gregor's slides before the recent X3J13 meeting,
he actually used CLASS-NAMED in a place or two, proving that that is the
more "natural" name for this feature. In a preprint of the paper "An
Object-Oriented Database System to Support an Integrated Programming
Environment", by Dan Weinreb et. al. of Symbolics, the authors describe
a database system linked closely with CLOS. "Entities" in this database
scheme have a name (always a symbol); the example entities which have a NAME
slot all have an "inverse" name mapping function called "<foo>-NAMED". The
PERSON entity has a NAME slot -- presumably to be accessed as PERSON-NAME;
and it also has, explicitly, the inverse PERSON-NAMED. Similarly for
DEPARTMENT-NAME and DEPARTMENT-NAMED. This is independent evidence of a
widespread convention: for a category of named things <foo>, the
name-to-thing mapping should be called <foo>-NAMED.
One possible objection: a named object with components will frequently have
names assigned to the components by suffixing "-<component-name>" to the
object name. Thus CLASS-NAMED might be mistaken for the NAMED slot of
classes. I claim it will never be so mistaken, primarily because of the
wide-spread use of the protocol just described, and also because there is a
tendency *not* to give names to components that are parsable (in English) as
a word in the past tense. Thus NAME and FROB are good component names for
classes, but NAMED and FROBBED are not. It just doesn't happen. If someone
wanted, say, a REDEFINED slot, as a way of remembering whether or not the
class had ever been redefined, he _probably_ would call it REDEFINED-P.
Note also that in the database paper just cited, there is an entity
COURSE with a TITLE slot; and the inverse name mapping is, very
appropriately, called COURSES-ENTITLED -- the "past tense" protocol.
[I might even suggest this simple linguistic device is worth noting
somewhere as a "good style" note.]
Benefits:
(1) refrain from making the mistake of suggesting that symbols have
a "class" slot; reduce false cognates on names like SYMBOL-PACKAGE.
(2) remove artificial blocks to the use of non-symbol names.
(3) align with the common protocol of using "<foo>-named" as the mapping
from names to <foo>'s.
Gregor said:
We already explained that we felt that it was more conventional with
CLtL to use symbol-class. Jonl's arguments here don't change my mind
about that. I think non symbol names are a horrible idea. It is a
major step away from a lisp-1. FIND-CLASS might not be a bad name
though.
Moon said:
The idea that naming a function SYMBOL-xxx implies that every symbol
necessarily has associated with it 32 bits of storage to hold an xxx is
simply ludicrous. So is the idea that language design should be
dictated by typos in Gregor's slides. There is no mumble-NAMED
convention in Common Lisp, and we felt it would be doing the language
a disservice to introduce a new convention instead of using one of
the existing ones. FIND-CLASS would be okay with me; in Flavors it's
(FLAVOR:FIND-FLAVOR name &optional (error-p t) (environment nil)).
What do others think?
-------
∂29-Apr-88 1436 Common-Lisp-Object-System-mailer no-next-method lexical function
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 29 Apr 88 14:36:08 PDT
Received: from Semillon.ms by ArpaGateway.ms ; 29 APR 88 14:30:50 PDT
Date: Fri, 29 Apr 88 14:30 PDT
From: Gregor.pa@Xerox.COM
Subject: no-next-method lexical function
To: common-lisp-object-system@sail.stanford.edu
Fcc: BD:>Gregor>mail>outgoing-mail-2.text.newest
Message-ID: <19880429213039.5.GREGOR@PORTNOY.parc.xerox.com>
Line-fold: no
One of the comments we received complained that there was no defined
protocol for what happened when call-next-method was called and there
was no next method. The full text of the comment was:
From ohkubo@pfrad.pf.fujitsu.junet Thu Apr 14 15:32:01 1988
Date: Wed, 13 Apr 88 17:05:24 JST
1. About the error signaled when next method doesn't exit.
The CLOS spec intends the user should check whether the next method exits
by next-method-p, but it will degrade the modularity, because the user
should concern about his method might have a method with the same name
which discriminate on the super class or combined with method combination.
In the system where multiple inheritance is supported, next method of
some method doesn't mean one unique method. There is a case where same
method have a next method in on case, and there isn't next method in another
case, depending on the context. (On the other hand, in Smalltalk 'super'
method can be decided statically). The method combination facility further
complicates the decision whether next method might be exit. This might
enforce the user should always use next-method-p.
To solve this problem, Object System should call a generic function named
such as 'no-next-method', when call-next-method is invoked but there isn't
such method, and the default method of 'no-next-method' should signal an
error. With this modification user can write 'no-next-method' which does
nothing or invokes error notifier. This mechanism is the same as
'no-applicable-method'.
Gregor said:
This is a good idea. We should add a generic function called
NEXT-METHOD-MISSING which receives the generic-function, method and the
arguments as its arguments.
(defmethod next-method-missing ((gf standard-generic-function)
(m standard-method)
&rest args)
(error "No next method"))
Moon said:
NO-NEXT-METHOD is a more consistent name. I don't understand what method
you propose it would receive as an argument; I think it should receive the
same arguments as NO-APPLICABLE-METHOD.
Gregor said:
I agree that no-next-method is a better name. The method I propose it
receive as an argument is the currently executing method. This gives
specializations of no-next-method which want to try to determine which
method to invoke more information to work with.
What do others think? (Heard this line before anywhere?)
-------
∂29-Apr-88 1527 Common-Lisp-Object-System-mailer Re: Reinitialization: check-initargs
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 29 Apr 88 15:27:12 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 395200; Fri 29-Apr-88 18:27:14 EDT
Date: Fri, 29 Apr 88 18:26 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: Reinitialization: check-initargs
To: Common-Lisp-Object-System@SAIL.STANFORD.EDU
In-Reply-To: <880428-093223-7329@Xerox>
Message-ID: <19880429222648.4.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: 28 Apr 88 09:32 PDT
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
(unless (check-keyword-arguments
(cons (class-prototype class) initargs)
(list #'allocate-instance
#'initialize-instance
#'initialize-new-instance)
(class-slot-initargs class))
(error "illegal initarg"))
But this doesn't work because each one of allocate-instance,
initialize-instance, and initialize-new-instance takes slightly
different arguments.
Unfortuntately, right. I have two patches for this, since I think the idea is
good. Both patches have problems. Here are the alternative patches.
1) The difference in arguments is that #'initialize-instance takes a second
required argument, slots-using-initforms.
Also allocate-instance takes a class where the other two take an instance.
I don't remember why we did it that way.
Also update-instance-for-redefined-class and update-instance-for-different-class
should contribute to the initialization argument checking in their respective
cases, but they take idiosyncratic arguments. If you assume that only the
first argument is specialized by any method (your patch#2 below), the other
arguments could be ignored. However, that assumption is quite unlikely to
be true for update-instance-for-different-class.
Instead, make slots-using-initforms be a keyword argument.
This doesn't solve the two problems I mentioned just above.
2) Change the argument structure for check-keyword-arguments
check-keyword-arguments required-arguments
key-word-arguments
generic-functions
&optional extra-allowed-keywords
Make required arguments be a list that can select the appropriate methods from
each generic funcion. If the list is too short, consider it equivalent to being
filled out with enough nils to be of the right length.
I just got another idea, which is to pass in a list of generic functions
and arguments to which to apply them. But that doesn't work because we
have forgotten that we are doing check-initargs, not
check-keyword-arguments, and it has to worry about slot-filling initargs
too. In 88-003 page 60 check-keyword-arguments was used as the name of
an entirely different function that has to do with congruence; let's not
get too confused here.
How about this idea?
check-initargs class initargs additional-calls
class - the class whose slot-filling initargs are relevant
initargs - the list of initargs to be checked
additional-calls - a list of calls that will be performed;
each call is a list whose first element is a generic
function (not the name of a generic function) and whose
remaining elements are arguments. Optional/keyword
arguments can (must?) be omitted from these lists since they do
not contribute to method applicability. If any applicable
method for any call accepts a keyword argument from initargs,
check-initargs regards that keyword argument as valid.
Thus (see 88-002 p.1-44):
(defmethod make-instance ((class standard-class) &rest initargs)
(setq initargs (default-initargs class initargs))
(check-initargs class initargs
`((,#'allocate-instance ,class)
(,#'initialize-new-instance ,(class-prototype class))
(,#'initialize-instance ,(class-prototype class) t)))
(let ....
check-initargs's implementation calls method-applicable-keywords
(88-003 p.27) except I believe the name of that function is a typo
and was supposed to be applicable-method-keywords. [Danny suggested
keywords-for-applicable-methods, that would be okay too.]
88-002 page 1-40 says that (something called by) make-instance signals
an error if an invalid initarg is supplied. CLtL page 62 says it is
an error if an argument pair has a keyword name not matched by any
parameter specifier. I am always in favor of argument checking, but
perhaps some of the implementors among us would prefer to make this
complex check-initargs processing an "is an error" situation so that
it can be deleted when compiling for speed. That's "an error should
be signaled" in 88-002 terminology.
....
However, there is a problem in using keywords-for-applicable-methods in
check-initargs. What value does it return if &rest or
&allow-other-keys appears in any method?
If we take Moon's suggestion of returning the symbol &allow-other-keys in this
case, then check-initargs cannnot use this value, since the default
methods for initialize-instance and allocate-instance have an &rest argument.
Hold on there. Read the last paragraph on p.1-29 of 88-002. &rest has no
effect on the set of acceptable keyword arguments; &rest is not at all
a synonym for &allow-other-keys. I don't think there is any problem
with keywords-for-applicable-methods returning the symbol &allow-other-keys
when an applicable method has &allow-other-keys in its lambda-list. This
will correctly cause check-initargs to return without signalling an error.
No predefined CLOS method has &allow-other-keys in its lambda-list.
∂29-Apr-88 1910 Common-Lisp-Object-System-mailer Re: Reinitialization: check-initargs
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 29 Apr 88 19:10:36 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 29 APR 88 19:07:58 PDT
Date: 29 Apr 88 19:07 PDT
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Re: Reinitialization: check-initargs
In-reply-to: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>'s message of
Fri, 29 Apr 88 18:26 EDT
To: Moon@STONY-BROOK.SCRC.Symbolics.COM
cc: Common-Lisp-Object-System@SAIL.STANFORD.EDU
Message-ID: <880429-190758-1574@Xerox>
I just got another idea, which is to pass in a list of generic
functions and arguments to which to apply them.
This can be made to work.
But that doesn't work because we have forgotten that we are doing
check-initargs, not check-keyword-arguments, and it has to worry
about slot-filling initargs too.
One doesn't have to worry about the slot-filling initargs since those can be
passed in as extra-allowed-keywords.
check-keyword-arguments key-word-arguments
generic-functions-and-arguments
&optional extra-allowed-keywords
keyword-arguments is a p-list of keyword arguments to be passed to the
generic-functions in generic-functions-and-arguments.
generic-functions-and-arguments is a list of lists, each containing a generic
function followed by a list of the required arguments that can select
appropriate methods.
extra-allowed-keywords is a list of additional allowed keywords.
make instance would call check-keyword-arguments this way
(defmethod make-instance ((class standard-class) &rest initargs)
(setq initargs (default-initargs class initargs))
(let((proto (class-prototype class)))
(unless (check-keyword-arguments
initargs
(list (list #'allocate-instance class)
(list #'initialize-instance proto nil)
(list #'initialize-new-instance proto))
(class-slot-initargs class))
(error "illegal initarg")))
.
.
.)
As for the check-keyword-arguments on page 60 of Chapter 3, it is the one that
is misnamed. It should be called something more like
check-method-keyword-arguments.
∂30-Apr-88 0156 Common-Lisp-Object-System-mailer type slot option
Received: from labrea.stanford.edu by SAIL.Stanford.EDU with TCP; 30 Apr 88 01:56:15 PDT
Received: by labrea.stanford.edu; Sat, 30 Apr 88 01:56:26 PDT
Received: from bhopal.lucid.com by edsel id AA11735g; Sat, 30 Apr 88 01:50:35 PDT
Received: by bhopal id AA10316g; Sat, 30 Apr 88 01:52:48 PDT
Date: Sat, 30 Apr 88 01:52:48 PDT
From: Jon L White <edsel!jonl@labrea.stanford.edu>
Message-Id: <8804300852.AA10316@bhopal.lucid.com>
To: Gregor.pa@xerox.com
Cc: common-lisp-object-system@sail.stanford.edu
In-Reply-To: Gregor.pa@Xerox.COM's message of Fri, 29 Apr 88 14:15 PDT <19880429211514.2.GREGOR@PORTNOY.parc.xerox.com>
Subject: type slot option
re: One of the comments we received attacked several problems with the :type
slot option. The complaint, which came from Dan Pierson, sees to be
that because the :type option is not enforced by automatically defined
accessors or slot-value, you can't count on it to protect a slot from
having the wrong type of value stored in it. It seems he is thinking of
the type option as a `semantic' feature, rather than an optional
compiler declaration.
Some of the comments you mailed out seem to be addressing this issue as
if it were yet another facet of the stock-hardware-inspired "declaration"
war. But in fact the criticism directed against it is precisely that it
is viewed only as an ignorable "declaration". Pierson's desires would be
fully satisfied, I think, if there were some mode in which the :type options
were enforced as a semantic feature. I've seen such comments on the
common-lisp mailing list too -- that there ought to be at least one mode
of interaction with the system such that defstruct slot access is always
"type-checked" (translate that to slot access for CLOS). Again, I emphasize
that this is not a LispM-versus-stock-hardware issue, since the type-checking
involved is not the kind that is being done by the special purpose hardware.
Interlisp had a feature like this that was a run-time checked declaration.
I can't remember right now what it was called.
Perhaps a reasonable way out of the situation is to "defer" it to CL's
treatment of the :type option in defstruct. If ever there is mandated
such a "mode" as I referred to for defstruct, then CLOS could follow the
same protocol.
-- JonL --
∂30-Apr-88 0316 Common-Lisp-Object-System-mailer FIND-CLASS
Received: from labrea.stanford.edu by SAIL.Stanford.EDU with TCP; 30 Apr 88 03:06:35 PDT
Received: by labrea.stanford.edu; Sat, 30 Apr 88 03:06:45 PDT
Received: from bhopal.lucid.com by edsel id AA11908g; Sat, 30 Apr 88 02:59:50 PDT
Received: by bhopal id AA10473g; Sat, 30 Apr 88 03:02:05 PDT
Date: Sat, 30 Apr 88 03:02:05 PDT
From: Jon L White <edsel!jonl@labrea.stanford.edu>
Message-Id: <8804301002.AA10473@bhopal.lucid.com>
To: gregor.pa@xerox.com
Cc: common-lisp-object-system@sail.stanford.edu
Subject: FIND-CLASS
I like Warren Harris's suggestion of 'FIND-CLASS', because of the parallel
to 'FIND-SYMBOL' and 'FIND-PACKAGE'. I had suggested 'CLASS-NAMED' only
because I saw it used once (by you), and because it followed the pattern
of Dan Weinreb's code examples.
No one seems to have commented yet about the need to flush CBOUNDP etc.
There is a red-herring here that I'd rather not waste time on -- that
is whether style dictates that a name "foo-bar" can only be used if
there is a "bar" slot. The issue about the poor name symbol-class is
that is has no reasonable analogy with the other functions named
symbol-<something>, neither implementationally nor conceptually.
-- JonL --
∂30-Apr-88 1019 Common-Lisp-Object-System-mailer Recovery
To: common-lisp-object-system@SAIL.Stanford.EDU
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>
Well, I've gotten well enough now that I can contemplate some serious
work on CLOS during the next 2 weeks.
Here are some comments on the recent written response mail:
On GENERIC-FUNCTION special form:
It's true I proposed it to be a special form. I did that so it
would be parallel to FUNCTION. I had even imagined some #<mumble>
reader macro for it. Unlike FUNCTION, GENERIC-FUNCTION can be a macro
for MAKE-INSTANCE. In Qlisp we have a macro called QLAMBDA which is
like LAMBDA except it cannot be used inside FUNCTION etc. It turns out
to be a drag because the differences between how you can use QLAMBDA
and how you can use LAMBDA seem gratuitous. Similarly, I thought that
folks would prefer to see GENERIC-FUNCTION be as similar to FUNCTION as
possible.
GENERIC-FUNCTION as a macro can efunctuate what it needs to inside the
#'lambda's that appear inside the method-forming part of the expansion of
the macro. I can imagine people making mistakes the first time they write
this macro.
On the :type slot option:
As you all recall, my original writeup of this option stated that
attempting to store an invalid type SHOULD signal an error. Moon objected
on the grounds that he did not want to have to ever check it, except when
other operations would naturally check the contents (such as during an
addition).
Thus, I never saw this as a compiler pragma only but as a semantic issue.
I would favor a redux to my original wording (yes, ``redux'' is the word I
mean).
On the name SYMBOL-CLASS:
I would be more upset with this name if SYMBOL-CLASS were a generic function.
On the setf function section:
I believe that if the next draft is really the X3J13 draft, we should not
include this section either as a section or an appendix. There is enough
of a statement within the rest of Chapters 1 & 2 that setf functions are
assumed that I doubt there is any chance that our intention that they be
adopted somehow gets lost.
On NEXT-METHOD-MISSING:
This is a good idea, so good that I had mistakenly thought
CALL-NEXT-METHOD invoked NO-APPLICABLE-METHOD in this case already.
On :DOCUMENTATION:
I have no opinion.
-rpg-
∂02-May-88 0659 Common-Lisp-Object-System-mailer Re: symbol-class is bad name
Received: from ti.com by SAIL.Stanford.EDU with TCP; 2 May 88 06:59:32 PDT
Received: by ti.com id AA15015; Mon, 2 May 88 08:58:13 CDT
Received: from Jenner by tilde id AA18960; Mon, 2 May 88 08:55:19 CDT
Message-Id: <2787573019-15236199@Jenner>
Date: Mon, 2 May 88 08:50:19 CDT
From: Patrick H Dussud <DUSSUD@Jenner.csc.ti.com>
Cc: common-lisp-object-system@SAIL.STANFORD.EDU
Subject: Re: symbol-class is bad name
In-Reply-To: Msg of Fri, 29 Apr 88 14:35 PDT from Gregor.pa@XEROX.COM
Gregor said:
We already explained that we felt that it was more conventional with
CLtL to use symbol-class. Jonl's arguments here don't change my mind
about that. I think non symbol names are a horrible idea. It is a
major step away from a lisp-1. FIND-CLASS might not be a bad name
though.
Moon said:
The idea that naming a function SYMBOL-xxx implies that every symbol
necessarily has associated with it 32 bits of storage to hold an xxx is
simply ludicrous. So is the idea that language design should be
dictated by typos in Gregor's slides. There is no mumble-NAMED
convention in Common Lisp, and we felt it would be doing the language
a disservice to introduce a new convention instead of using one of
the existing ones. FIND-CLASS would be okay with me; in Flavors it's
(FLAVOR:FIND-FLAVOR name &optional (error-p t) (environment nil)).
What do others think?
-------
I don't share JonL concerns for SYMBOL-CLASS. Since it is likely to be
an obstacle for us at X3J13, I think that FIND-CLASS is OK. Adding an
error-p optional argument is good if CBOUNDP is removed.
Patrick.
∂02-May-88 0714 Common-Lisp-Object-System-mailer generic-function special form
Received: from ti.com by SAIL.Stanford.EDU with TCP; 2 May 88 07:14:48 PDT
Received: by ti.com id AA15076; Mon, 2 May 88 09:13:12 CDT
Received: from Jenner by tilde id AA19148; Mon, 2 May 88 09:03:13 CDT
Message-Id: <2787573500-15265067@Jenner>
Date: Mon, 2 May 88 08:58:20 CDT
From: Patrick H Dussud <DUSSUD@Jenner.csc.ti.com>
To: Gregor.pa@XEROX.COM
Cc: common-lisp-object-system@SAIL.STANFORD.EDU
Subject: generic-function special form
In-Reply-To: Msg of Fri, 29 Apr 88 14:25 PDT from Gregor.pa@XEROX.COM
Date: Fri, 29 Apr 88 14:25 PDT
From: Gregor.pa@XEROX.COM
Subject: generic-function special form
One of the comments we received was:
Date: Fri, 15 Apr 88 13:43 PDT
From: David N Gray <Gray@DSG.csc.ti.com>
It is not apparent why GENERIC-FUNCTION needs to be a special form
instead of a macro.
Gregor said:
Because Common Lisp doesn't have lambda macros.
Moon said:
No, that's wrong, because GENERIC-FUNCTION is not something that can be
used inside the FUNCTION special form. In other words, GENERIC-FUNCTION
evaluates, it doesn't efunctuate. As far as I can see GENERIC-FUNCTION
could be a macro that expands into MAKE-INSTANCE <generic-function-class>
and a bunch of initargs including some that are forms that construct methods.
I think Gray is right on this one and it's a mistake in the document.
We should check with RPG, who proposed this.
Gregor said:
I am surprised to here that generic-function cannot be used inside the
function special form. It doesn't say that in the documentation, and
since the method bodies are supplied as forms, I think this must
efunctuate. It must capture the lexical scope it was used in or else
what is it worth?
What do others think?
-------
I think that a macro will work. A macro can return a form that capture
the lexical environment if it contains lambda forms.
Patrick.
∂02-May-88 0746 Common-Lisp-Object-System-mailer no-next-method lexical function
Received: from ti.com by SAIL.Stanford.EDU with TCP; 2 May 88 07:46:35 PDT
Received: by ti.com id AA15303; Mon, 2 May 88 09:45:26 CDT
Received: from Jenner by tilde id AA20028; Mon, 2 May 88 09:38:51 CDT
Message-Id: <2787575636-15393416@Jenner>
Date: Mon, 2 May 88 09:33:56 CDT
From: Patrick H Dussud <DUSSUD@Jenner.csc.ti.com>
Cc: common-lisp-object-system@SAIL.STANFORD.EDU
Subject: no-next-method lexical function
In-Reply-To: Msg of Fri, 29 Apr 88 14:30 PDT from Gregor.pa@XEROX.COM
Gregor said:
This is a good idea. We should add a generic function called
NEXT-METHOD-MISSING which receives the generic-function, method and the
arguments as its arguments.
(defmethod next-method-missing ((gf standard-generic-function)
(m standard-method)
&rest args)
(error "No next method"))
Moon said:
NO-NEXT-METHOD is a more consistent name. I don't understand what method
you propose it would receive as an argument; I think it should receive the
same arguments as NO-APPLICABLE-METHOD.
Gregor said:
I agree that no-next-method is a better name. The method I propose it
receive as an argument is the currently executing method. This gives
specializations of no-next-method which want to try to determine which
method to invoke more information to work with.
What do others think? (Heard this line before anywhere?)
-------
I think the concept of NO-NEXT-METHOD is fine. I don't have any
opinions about the method argument. I'd like to see David's objection
to it.
Patrick.
∂02-May-88 0746 Common-Lisp-Object-System-mailer no-next-method lexical function
Received: from ti.com by SAIL.Stanford.EDU with TCP; 2 May 88 07:46:43 PDT
Received: by ti.com id AA15307; Mon, 2 May 88 09:45:31 CDT
Received: from Jenner by tilde id AA20039; Mon, 2 May 88 09:39:05 CDT
Message-Id: <2787575653-15394441@Jenner>
Date: Mon, 2 May 88 09:34:13 CDT
From: Patrick H Dussud <DUSSUD@Jenner.csc.ti.com>
Cc: common-lisp-object-system@SAIL.STANFORD.EDU
Subject: no-next-method lexical function
In-Reply-To: Msg of Fri, 29 Apr 88 14:30 PDT from Gregor.pa@XEROX.COM
Gregor said:
This is a good idea. We should add a generic function called
NEXT-METHOD-MISSING which receives the generic-function, method and the
arguments as its arguments.
(defmethod next-method-missing ((gf standard-generic-function)
(m standard-method)
&rest args)
(error "No next method"))
Moon said:
NO-NEXT-METHOD is a more consistent name. I don't understand what method
you propose it would receive as an argument; I think it should receive the
same arguments as NO-APPLICABLE-METHOD.
Gregor said:
I agree that no-next-method is a better name. The method I propose it
receive as an argument is the currently executing method. This gives
specializations of no-next-method which want to try to determine which
method to invoke more information to work with.
What do others think? (Heard this line before anywhere?)
-------
I think the concept of NO-NEXT-METHOD is fine. I don't have any
opinion about the method argument. I'd like to see David's objection
to it.
Patrick.
∂02-May-88 0747 Common-Lisp-Object-System-mailer Re: type slot option
Received: from ti.com by SAIL.Stanford.EDU with TCP; 2 May 88 07:46:48 PDT
Received: by ti.com id AA15311; Mon, 2 May 88 09:45:36 CDT
Received: from Jenner by tilde id AA20120; Mon, 2 May 88 09:42:55 CDT
Message-Id: <2787575884-15408314@Jenner>
Date: Mon, 2 May 88 09:38:04 CDT
From: Patrick H Dussud <DUSSUD@Jenner.csc.ti.com>
Cc: common-lisp-object-system@SAIL.STANFORD.EDU
Subject: Re: type slot option
In-Reply-To: Msg of Fri, 29 Apr 88 14:15 PDT from Gregor.pa@XEROX.COM
Date: Fri, 29 Apr 88 14:15 PDT
From: Gregor.pa@XEROX.COM
Subject: type slot option
Moon said:
Common Lisp defines errors with respect to a single program. Common
Lisp does not address the issue of how one program can protect itself
against language violations committed by another program running in the
same Lisp. I don't think this problem is specific to CLOS in any way.
I don't think it's CLOS's business to do anything about it. Of course
I'd like to see Common Lisp fixed to eliminate this problem, for example
by completely eliminating the concept of type declaration. However in
the real world that is not going to happen; historically programmers
have been eager to accept incorrect code for the sake of efficiency.
Gregor said:
This is a problem. The reason we are losing is that we are thinking of
this :type slot option as a compiler feature whereas some user might
think of it as a real semantic feature. There are several ways out:
- drop the :type slot option entirely
- say that writer methods will check the type, but setf of
slot-value might not
- say that everything which write into the slot will check
the type
- say that everything which write into the slot should check
the type
- leave things the way they are, but make it clear that it
is the job of the user code to enforce the type option.
Moon said:
You're right that :TYPE is a compiler optimization, not a semantic
feature. It's like the TYPE declaration in that respect. If slot
options had been defined in a syntactically consistent way (i.e.
enclosed in parentheses like class options) then the syntax of this
slot option could have been based on the syntax of DECLARE and just
possibly people would be less confused about what it means. I'm not
seriously proposing that; I'd rather eliminate the option, if we're
going to make such a large change.
What should we do about this?
-------
I think this issue is too big to be decided in this group. I wouldn't
take decision before asking the whole X3J13. In case it produces an
endless and intractable discussion, I would be in favor of turning off
this option until a concensus emerges.
Patrick.
∂02-May-88 0850 Common-Lisp-Object-System-mailer Re: type slot option
Received: from Sun.COM by SAIL.Stanford.EDU with TCP; 2 May 88 08:50:08 PDT
Received: from snail.sun.com by Sun.COM (4.0/SMI-4.0)
id AA23465; Mon, 2 May 88 08:49:02 PDT
Received: from suntana.sun.com by snail.sun.com (4.0/SMI-3.2)
id AA21590; Mon, 2 May 88 08:47:32 PDT
Received: from localhost by suntana.sun.com (3.2/SMI-3.2)
id AA13800; Mon, 2 May 88 08:41:32 PDT
Message-Id: <8805021541.AA13800@suntana.sun.com>
To: Gregor.pa@Xerox.COM
Cc: common-lisp-object-system@sail.stanford.edu
Subject: Re: type slot option
In-Reply-To: Your message of Fri, 29 Apr 88 14:15:00 -0700.
<19880429211514.2.GREGOR@PORTNOY.parc.xerox.com>
Date: Mon, 02 May 88 08:41:29 -0700
From: kempf@Sun.COM
I don't think we should eliminate the :type option, but I think we
ought to make it work exactly like the defstruct :type option on
pg. 310 of CLtL. I don't personally believe that this is the "right"
way to do typing, but it is consistent with the Common Lisp approach
of type declarations as advice to the compiler in an otherwise
latently typed language. If we eliminate it, we make defclass
inconsistent with defstruct, if we change the semantics, we make defclass
inconsistent with the rest of Common Lisp.
jak
∂02-May-88 0854 Common-Lisp-Object-System-mailer Re: documentation slot option
Received: from Sun.COM by SAIL.Stanford.EDU with TCP; 2 May 88 08:54:07 PDT
Received: from snail.sun.com by Sun.COM (4.0/SMI-4.0)
id AA23525; Mon, 2 May 88 08:53:15 PDT
Received: from suntana.sun.com by snail.sun.com (4.0/SMI-3.2)
id AA21787; Mon, 2 May 88 08:51:47 PDT
Received: from localhost by suntana.sun.com (3.2/SMI-3.2)
id AA13811; Mon, 2 May 88 08:45:47 PDT
Message-Id: <8805021545.AA13811@suntana.sun.com>
To: Gregor.pa@Xerox.COM
Cc: common-lisp-object-system@sail.stanford.edu
Subject: Re: documentation slot option
In-Reply-To: Your message of Fri, 29 Apr 88 14:20:00 -0700.
<19880429212048.3.GREGOR@PORTNOY.parc.xerox.com>
Date: Mon, 02 May 88 08:45:45 -0700
From: kempf@Sun.COM
I'm mildly in favor of this, but don't feel particularly strongly about it.
It seems like a good idea to encourage documentation, whether this way
or another is irrelevent. As to whether it would apply to all methods
defined on the accessor generic function, I agree this may not be true, but
the same could be said for documentation strings for other methods.
As Gregor mentioned, it seems well defined enough that it would be
simple to put in.
jak
∂02-May-88 0903 Common-Lisp-Object-System-mailer Re: generic-function special form
Received: from Sun.COM by SAIL.Stanford.EDU with TCP; 2 May 88 09:03:10 PDT
Received: from snail.sun.com by Sun.COM (4.0/SMI-4.0)
id AA23736; Mon, 2 May 88 09:02:21 PDT
Received: from suntana.sun.com by snail.sun.com (4.0/SMI-3.2)
id AA22286; Mon, 2 May 88 09:00:42 PDT
Received: from localhost by suntana.sun.com (3.2/SMI-3.2)
id AA13841; Mon, 2 May 88 08:54:41 PDT
Message-Id: <8805021554.AA13841@suntana.sun.com>
To: Gregor.pa@Xerox.COM
Cc: common-lisp-object-system@sail.stanford.edu
Subject: Re: generic-function special form
In-Reply-To: Your message of Fri, 29 Apr 88 14:25:00 -0700.
<19880429212530.4.GREGOR@PORTNOY.parc.xerox.com>
Date: Mon, 02 May 88 08:54:39 -0700
From: kempf@Sun.COM
Arguments on the side of making it a special form are those cited by RPG
and Gregor, namely that consistency between the way function and
generic-function work seems like a good idea (RPG's qlambda example) and
the need for capturing the lexical environment (Gregor). On the minus
side is the stated goal of Common Lisp to limit the number of special
forms and the obvious macroexpansion for generic-function.
I tend to think that generic-function should be a special form, for
the arguments cited, and because it seems like a different enough
piece of functionality to justify going beyond the goal of limiting
special forms.
jak
∂02-May-88 0909 Common-Lisp-Object-System-mailer Re: no-next-method lexical function
Received: from Sun.COM by SAIL.Stanford.EDU with TCP; 2 May 88 09:09:14 PDT
Received: from snail.sun.com by Sun.COM (4.0/SMI-4.0)
id AA23837; Mon, 2 May 88 09:08:22 PDT
Received: from suntana.sun.com by snail.sun.com (4.0/SMI-3.2)
id AA22602; Mon, 2 May 88 09:06:43 PDT
Received: from localhost by suntana.sun.com (3.2/SMI-3.2)
id AA13865; Mon, 2 May 88 09:00:41 PDT
Message-Id: <8805021600.AA13865@suntana.sun.com>
To: Gregor.pa@Xerox.COM
Cc: common-lisp-object-system@sail.stanford.edu
Subject: Re: no-next-method lexical function
In-Reply-To: Your message of Fri, 29 Apr 88 14:30:00 -0700.
<19880429213039.5.GREGOR@PORTNOY.parc.xerox.com>
Date: Mon, 02 May 88 09:00:39 -0700
From: kempf@Sun.COM
This seems like a special case of no-applicable-method which could be
handled by providing another method on no-applicable-method which
discriminated on a function object rather than generic function:
(defmethod no-applicable-method ((called-function function) &rest arguments)
(error "No applicable method when ~S was called with arguments ~S.~%"
called-function arguments
)
)
If call-next-method failed to find a next method, the error message would
print showing that the function called was call-next-method and the
arguments.
Seems a better idea to use oo-programming in this case (specializing the
more general case) than to add another function, but I'm not opposed to
that if the rest of the committee feels it is a better idea.
jak
∂02-May-88 0913 Common-Lisp-Object-System-mailer Re: symbol-class is bad name
Received: from Sun.COM by SAIL.Stanford.EDU with TCP; 2 May 88 09:13:25 PDT
Received: from snail.sun.com by Sun.COM (4.0/SMI-4.0)
id AA23939; Mon, 2 May 88 09:12:32 PDT
Received: from suntana.sun.com by snail.sun.com (4.0/SMI-3.2)
id AA22754; Mon, 2 May 88 09:10:55 PDT
Received: from localhost by suntana.sun.com (3.2/SMI-3.2)
id AA13873; Mon, 2 May 88 09:04:54 PDT
Message-Id: <8805021604.AA13873@suntana.sun.com>
To: Gregor.pa@Xerox.COM
Cc: common-lisp-object-system@sail.stanford.edu
Subject: Re: symbol-class is bad name
In-Reply-To: Your message of Fri, 29 Apr 88 14:35:00 -0700.
<19880429213546.6.GREGOR@PORTNOY.parc.xerox.com>
Date: Mon, 02 May 88 09:04:52 -0700
From: kempf@Sun.COM
I don't particularly care what this bit of functionality is named, so long
as it is consistent with Common Lisp and the rest of the functions dealing
with naming in CLOS.
Warren's idea of find-class sounds fine. The rest of the functions dealing
with naming will need to be changed to reflect the new convention.
jak
∂03-May-88 1113 Common-Lisp-Object-System-mailer Re: no-next-method lexical function
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 3 May 88 11:12:53 PDT
Received: from Semillon.ms by ArpaGateway.ms ; 03 MAY 88 11:05:29 PDT
Date: Tue, 3 May 88 11:05 PDT
From: Gregor.pa@Xerox.COM
Subject: Re: no-next-method lexical function
To: kempf@Sun.COM
cc: common-lisp-object-system@sail.stanford.edu
Fcc: BD:>Gregor>mail>outgoing-mail-2.text.newest
In-Reply-To: <8805021600.AA13865@suntana.sun.com>
Message-ID: <19880503180516.1.GREGOR@PORTNOY.parc.xerox.com>
Line-fold: no
Date: Mon, 02 May 88 09:00:39 -0700
From: kempf@Sun.COM
This seems like a special case of no-applicable-method which could be
handled by providing another method on no-applicable-method which
discriminated on a function object rather than generic function:
If call-next-method failed to find a next method, the error message would
print showing that the function called was call-next-method and the
arguments.
I don't believe this is appropriate, because call-next-method itself
isn't doing any method lookup. Another way of saying this is that
call-next-method is not a generic-function that is failing to find an
applicable method.
-------
∂03-May-88 1112 Common-Lisp-Object-System-mailer Re: symbol-class is bad name
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 3 May 88 11:12:48 PDT
Received: from Semillon.ms by ArpaGateway.ms ; 03 MAY 88 11:02:42 PDT
Date: Tue, 3 May 88 11:02 PDT
From: Gregor.pa@Xerox.COM
Subject: Re: symbol-class is bad name
To: kempf@Sun.COM, Patrick H Dussud <DUSSUD@Jenner.csc.ti.com>, Dick Gabriel
<RPG@SAIL.Stanford.EDU>, Jon L White <edsel!jonl@labrea.stanford.edu>
cc: common-lisp-object-system@SAIL.Stanford.EDU
Fcc: BD:>Gregor>mail>outgoing-mail-2.text.newest
In-Reply-To: <8805021604.AA13873@suntana.sun.com>,
<2787573019-15236199@Jenner>,
The message of 30 Apr 88 10:19 PDT from Dick Gabriel
<RPG@SAIL.Stanford.EDU>,
<8804301002.AA10473@bhopal.lucid.com>,
<19880429213546.6.GREGOR@PORTNOY.parc.xerox.com>
Message-ID: <19880503180226.0.GREGOR@PORTNOY.parc.xerox.com>
Line-fold: no
Here is another thought on the symbol-class issue. I believe this argues
for keeping the name symbol-class.
Consider the situation if we had a true lisp-1. If that were the case,
classes, functions and `variables' would share the same namespace. For
example (using a Scheme-like notation) the following program lexically
defines a class named foo and some operations on it.
(define (foo-package)
(defclass foo ()
((x :initarg x)
(y :initarg y)))
(define (foo-p x)
(typep x foo))
(define (make-foo x y z)
(make-instance foo 'x x 'y y))
(define (foo-distance f)
(sqrt ...))
)
I understand that the analogy from this to the symbol-class/find-class
name issue is at best clouded. But, I do believe this argues for
keeping the name symbol-class. The idea is that only a symbol can name
a class, so the function should have the string "symbol" in it.
-------
∂03-May-88 1315 Common-Lisp-Object-System-mailer no-applicable-method
To: common-lisp-object-system@SAIL.Stanford.EDU
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>
Gregor writes:
``I don't believe this is appropriate, because call-next-method itself
isn't doing any method lookup. Another way of saying this is that
call-next-method is not a generic-function that is failing to find an
applicable method.''
I think his reasoning is not correct and suffers from making distinctions
that aren't important. What does CALL-NEXT-METHOD do? Assume we are
talking about primary methods. There is a set of applicable methods
that are ordered from most specific to least specific. If call-next-method
is invoked, the next most specific applicable method is invoked. If there
is none, then there is no less specific applicable method.
If you are in the :around case, if there is no less specific :around method
the cluster of applicable :before, primary, and :after methods are invoked.
These sound as if the problem is that there is no applicable method.
My question is, where is the necessity of method lookup generic function
invocation in the semantics of NO-APPLICABLE-METHOD?
-rpg-
∂03-May-88 1454 Common-Lisp-Object-System-mailer Re: no-applicable-method
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 3 May 88 14:54:06 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 03 MAY 88 14:50:40 PDT
Date: 3 May 88 14:50 PDT
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Re: no-applicable-method
In-reply-to: Dick Gabriel <RPG@SAIL.Stanford.EDU>'s message of 03 May 88 13:15
PDT
To: RPG@SAIL.Stanford.EDU
cc: common-lisp-object-system@SAIL.Stanford.EDU
Message-ID: <880503-145040-6024@Xerox>
Gregor writes:
``I don't believe this is appropriate, because call-next-method itself
isn't doing any method lookup. Another way of saying this is that
call-next-method is not a generic-function that is failing to find an
applicable method.''
RPG writes
``I think his reasoning is not correct and suffers from making distinctions
that aren't important. What does CALL-NEXT-METHOD do? Assume we are
talking about primary methods. There is a set of applicable methods
that are ordered from most specific to least specific. If call-next-method
is invoked, the next most specific applicable method is invoked. If there
is none, then there is no less specific applicable method.
If you are in the :around case, if there is no less specific :around method
the cluster of applicable :before, primary, and :after methods are invoked.
These sound as if the problem is that there is no applicable method.
My question is, where is the necessity of method lookup generic function
invocation in the semantics of NO-APPLICABLE-METHOD? ''
I think the critical issue here is that for intelligent error handling,
different arguments are necessary for NO-NEXT-METHOD and NO-APPLICABLE-METHOD.
NO-APPLICABLE-METHOD only needs the generic function and the arguments.
NO-NEXT-METHOD also needs the method that contained the call to
CALL-NEXT-METHOD. Hence, these two need to be different functions.
∂03-May-88 1536 Common-Lisp-Object-System-mailer Re: no-applicable-method
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 3 May 88 15:36:06 PDT
Received: from Semillon.ms by ArpaGateway.ms ; 03 MAY 88 15:31:29 PDT
Date: Tue, 3 May 88 15:31 PDT
From: Gregor.pa@Xerox.COM
Subject: Re: no-applicable-method
To: Dick Gabriel <RPG@SAIL.Stanford.EDU>
cc: common-lisp-object-system@SAIL.Stanford.EDU
Fcc: BD:>Gregor>mail>outgoing-mail-2.text.newest
In-Reply-To: The message of 3 May 88 13:15 PDT from Dick Gabriel
<RPG@SAIL.Stanford.EDU>
Message-ID: <19880503223117.3.GREGOR@PORTNOY.parc.xerox.com>
Line-fold: no
Date: 03 May 88 13:15 PDT
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>
These sound as if the problem is that there is no applicable method.
My question is, where is the necessity of method lookup generic function
invocation in the semantics of NO-APPLICABLE-METHOD?
Well, this may be so, but I still have a problem with Jim's proposal
which is that no-applicable-method doesn't really take the appropriate
arguments for this case. Without knowing what method the
call-next-method was called from (or at least which generic function),
it won't be possible to do anything really interesting in the no
applicable method case.
In addition, it won't be possible for users to further specialize this
case of no-applicable-method. The only possible specializations are
function and (eql #'call-next-method). With no-next-method, the user
can do something like:
;;;
;;; My method is a class of method that just returns nil from
;;; call-next-method if there is no next method.
;;;
(defclass my-method (standard-method)
())
(defmethod no-applicable-method ((gf standard-generic-function)
(m my-method)
&rest ignore)
nil)
-------
∂03-May-88 2125 Common-Lisp-Object-System-mailer Re: symbol-class is bad name
Received: from Score.Stanford.EDU by SAIL.Stanford.EDU with TCP; 3 May 88 21:25:04 PDT
Received: from hplabs.HP.COM by SCORE.STANFORD.EDU with TCP; Tue 3 May 88 21:19:40-PDT
Received: from hplms2.HP.COM (hplms2) by hplabs.HP.COM with SMTP ; Tue, 3 May 88 13:46:44 PST
Received: from hplwhh.HPL.HP.COM (hplwhh.hpl.hp.com) by hplms2.HP.COM; Tue, 3 May 88 14:46:23 pdt
Received: from hplwhh by hplwhh.HPL.HP.COM; Tue, 3 May 88 14:44:49 pdt
To: Gregor.pa@Xerox.COM
Cc: common-lisp-object-system@SAIL.Stanford.EDU
Subject: Re: symbol-class is bad name
X-Mailer: mh6.5
In-Reply-To: Your message of Tue, 03 May 88 11:02:00 -0700.
<19880503180226.0.GREGOR@PORTNOY.parc.xerox.com>
Date: Tue, 03 May 88 14:44:46 PDT
Message-Id: <11430.578699086@hplwhh>
From: Warren Harris <harris%hplwhh@hplabs.HP.COM>
> Consider the situation if we had a true lisp-1. If that were the case,
> classes, functions and `variables' would share the same namespace.
> The idea is that only a symbol can name
> a class, so the function should have the string "symbol" in it.
I think symbol-class would be a good name if symbol-<whatever> had some
consistency to it. But it doesn't. I don't like the fact that
symbol-package does not name a package. If I say:
(symbol-package 'pcl)
I might get:
#<Package USER #x223112>
Also what does symbol-name name? Is a string a name? Should symbol-name
return the symbol itself since symbols are intended to be used for naming?
The fact is that we don't have a lisp-1, but more like a lisp-5. I tend to
think of symbols as structures with slots that contain specific types of
data. The symbol-package slot can be thought to contain a package, but
does not "name" one. Similarly the symbol-function slot contains a
function. This same function may be contained somewhere else too.
Symbol-name contains a string. Symbol-plist contains a property list.
Symbol-class is a fine name, provided we establish the convension that
symbols are used for naming in lisp (Common Lisp that is, not Scheme). I
just don't think they're really thought of that way in practice. There's
just this kludgy thing called the interpreter that tends to use them that
way some times.
Warren
P.S. Maybe we should just pick a meaningless name in the typical lisp
tradition. Classics like CDR, NCONC, RPLACA and PSETF come to mind. Or
how about FOO? Nobody's really used FOO yet.
∂03-May-88 2337 Common-Lisp-Object-System-mailer symbol-class is bad name
Received: from labrea.stanford.edu by SAIL.Stanford.EDU with TCP; 3 May 88 23:37:33 PDT
Received: by labrea.stanford.edu; Tue, 3 May 88 23:37:45 PDT
Received: from bhopal.lucid.com by edsel id AA27550g; Tue, 3 May 88 23:30:46 PDT
Received: by bhopal id AA23219g; Tue, 3 May 88 23:33:17 PDT
Date: Tue, 3 May 88 23:33:17 PDT
From: Jon L White <edsel!jonl@labrea.stanford.edu>
Message-Id: <8805040633.AA23219@bhopal.lucid.com>
To: Gregor.pa@xerox.com
Cc: common-lisp-object-system@sail.stanford.edu
In-Reply-To: Gregor.pa@Xerox.COM's message of Tue, 3 May 88 11:02 PDT <19880503180226.0.GREGOR@PORTNOY.parc.xerox.com>
Subject: symbol-class is bad name
re: Consider the situation if we had a true lisp-1. If that were the case,
classes, functions and `variables' would share the same namespace.
Not relevant. global datastructures can be reasonably named by techniques
other than global variables. Strings, for example.
re: The idea is that only a symbol can name a class, . . .
This is a retro-grade assumption. Part of my criticism was precisely that
the name symbol-class prematurely tends to close off the name extension
issue. Since CLOS has already swallowed the pill of "unnamed classes"
then there is no logical ground within CLOS itself against reasonable
name extension. It's an exact parallel of "unnamed functions" to
"function specs".
re: The idea is that only a symbol can name a class, so the function should
have the string "symbol" in it.
If ever we need to invoke moon's argument-by-reduction-to-ridiculous, this
is a place to do so. E.g., since only strings name packages, then the
function that finds packages should have the string "string" in it's name?
Given that you yourself were at one time calling the functionality
CLASS-NAMED (from LOOPS days?), and that other non-LispMachine types
object to calling the functionality SYMBOL-CLASS for essentially the
same reasons as I listed, then I wonder what the problem is all about?
-- JonL --
∂04-May-88 0022 Common-Lisp-Object-System-mailer no-applicable-method
Received: from labrea.stanford.edu by SAIL.Stanford.EDU with TCP; 4 May 88 00:22:00 PDT
Received: by labrea.stanford.edu; Wed, 4 May 88 00:22:05 PDT
Received: from bhopal.lucid.com by edsel id AA27611g; Wed, 4 May 88 00:10:08 PDT
Received: by bhopal id AA23297g; Wed, 4 May 88 00:12:39 PDT
Date: Wed, 4 May 88 00:12:39 PDT
From: Jon L White <edsel!jonl@labrea.stanford.edu>
Message-Id: <8805040712.AA23297@bhopal.lucid.com>
To: Gregor.pa@xerox.com
Cc: RPG@sail.stanford.edu, common-lisp-object-system@sail.stanford.edu
In-Reply-To: Gregor.pa@Xerox.COM's message of Tue, 3 May 88 15:31 PDT <19880503223117.3.GREGOR@PORTNOY.parc.xerox.com>
Subject: no-applicable-method
re: With no-next-method, the user can do something like:
. . .
(defmethod no-applicable-method ((gf standard-generic-function)
(m my-method)
&rest ignore)
nil)
Didn't you mean (defmethod no-next-method ...)?
Danny's point is well taken: NO-APPLICABLE-METHOD is one kind of error, and
it is useful when debugging to get a different kind of error when there *are*
applicable methods, but some one of them presumes that there are more in the
method list than actually are there (i.e., CALL-NEXT-METHOD runs out). His
argument is based on the variation in number of arguments passed, and your
example exploits essentially this. But I think there is a more fundamental
case that can be made for keeping the two "error" functions separate.
In the first case, one would think of repairing the error by adding some
defmethod somewhere to cover a missing case, or to change a some caller
who is passing an "illegal" value. But the second kind of error takes one
into a much more complex domain -- involving more advanced concepts such
as method combination and possibly meta-object protocols [perish the
thought that call-next-method failed in a function that really wasn't
a standard-generic-function, or where the method combination was someone's
hallucinative speciality). Even if you could cram one interface into
the other, by passing differing arguments or whateer, it would be a less
desirable user interface.
-- JonL --
∂04-May-88 0850 Common-Lisp-Object-System-mailer Re: no-applicable-method
Received: from Sun.COM by SAIL.Stanford.EDU with TCP; 4 May 88 08:50:50 PDT
Received: from snail.sun.com by Sun.COM (4.0/SMI-4.0)
id AA28593; Wed, 4 May 88 08:49:55 PDT
Received: from suntana.sun.com by snail.sun.com (4.0/SMI-3.2)
id AA13044; Wed, 4 May 88 08:48:19 PDT
Received: from localhost by suntana.sun.com (3.2/SMI-3.2)
id AA15982; Wed, 4 May 88 08:42:22 PDT
Message-Id: <8805041542.AA15982@suntana.sun.com>
To: Danny Bobrow <Bobrow.pa@Xerox.COM>
Cc: RPG@SAIL.Stanford.EDU, common-lisp-object-system@SAIL.Stanford.EDU
Subject: Re: no-applicable-method
In-Reply-To: Your message of 03 May 88 14:50:00 -0700.
<880503-145040-6024@Xerox>
Date: Wed, 04 May 88 08:42:20 -0700
From: kempf@Sun.COM
Gregor writes:
>>I don't believe this is appropriate, because call-next-method itself
>>isn't doing any method lookup. Another way of saying this is that
>>call-next-method is not a generic-function that is failing to find an
>>applicable method.''
RPG writes
>>I think his reasoning is not correct and suffers from making distinctions
>>that aren't important. What does CALL-NEXT-METHOD do? Assume we are
>>talking about primary methods. There is a set of applicable methods
>>that are ordered from most specific to least specific. If call-next-method
>>is invoked, the next most specific applicable method is invoked. If there
>>is none, then there is no less specific applicable method.
Danny writes:
>>I think the critical issue here is that for intelligent error handling,
>>different arguments are necessary for NO-NEXT-METHOD and NO-APPLICABLE-METHOD.
>>NO-APPLICABLE-METHOD only needs the generic function and the arguments.
>>NO-NEXT-METHOD also needs the method that contained the call to
>>CALL-NEXT-METHOD. Hence, these two need to be different functions.
Gregor writes:
>>In addition, it won't be possible for users to further specialize this
>>case of no-applicable-method. The only possible specializations are
>>function and (eql #'call-next-method). With no-next-method, the user
>>can do something like:
There are two answers to this question, a short one and a longer one.
The short one is that anyone doing development is probably going to
look at a stack backtrace to find out where the error occured anyway,
so the originating method should be available from that.
However, Gregor has made a good point, in that specializations on
no-applicable-method would be difficult, which leads to the
longer answer. The problem there is that the parameter specializers
in my original proposal were not correct. The actual method definition
should look like:
(defmethod no-applicable-method ((method standard-method) &rest arguments)
(error "No applicable method for CALL-NEXT-METHOD from method ~S having~
argument list ~S.~%" method arguments)
)
This would allow message forwarding, specialization for custom methods, etc.
If, for some reason, the generic function is of interest in an error
report, then it can be obtained by using the reader operation
(method-generic-function) on the method. If, for some reason, someone
wants to customize so that forwarding or the error message depends on
both the generic function and the method, they can write an additional
method which does the forwarding or error message, and call it from
no-applicable-method:
(defmethod no-applicable-method ((method my-method) &rest arguments)
(apply #'my-no-matching-method method (my-method-generic-function) arguments)
)
In the case of standard-generic-function and standard-method, enough
information in the error report can be obtained from the method object
where the call originated and the arguments to the call.
The semantics of no-applicable-method would seem to be general enough to
cover no next method as a special case.
∂04-May-88 1053 Common-Lisp-Object-System-mailer no-next-method | no-applicable-method
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 4 May 88 10:52:16 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 397829; Wed 4-May-88 13:52:02 EDT
Date: Wed, 4 May 88 13:51 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: no-next-method | no-applicable-method
To: common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: <19880429213039.5.GREGOR@PORTNOY.parc.xerox.com>,
<2787575636-15393416@Jenner>,
<8805021600.AA13865@suntana.sun.com>,
<19880503180516.1.GREGOR@PORTNOY.parc.xerox.com>,
The message of 3 May 88 16:15 EDT from Dick Gabriel <RPG@SAIL.Stanford.EDU>,
<880503-145040-6024@Xerox>,
<19880503223117.3.GREGOR@PORTNOY.parc.xerox.com>,
<8805040712.AA23297@bhopal.lucid.com>,
<8805041542.AA15982@suntana.sun.com>
Message-ID: <19880504175137.5.MOON@EUPHRATES.SCRC.Symbolics.COM>
I think we are all agreed that CALL-NEXT-METHOD, when there is no next
method, should call a user specializable generic function, rather than
directly signalling an error as 88-002 says. The only point of contention
is what should the name of that generic function be.
Date: Fri, 29 Apr 88 14:30 PDT
From: Gregor.pa@Xerox.COM
One of the comments we received complained that there was no defined
protocol for what happened when call-next-method was called and there
was no next method....
Moon said:
NO-NEXT-METHOD is a more consistent name. I don't understand what method
you propose it would receive as an argument; I think it should receive the
same arguments as NO-APPLICABLE-METHOD.
Gregor said:
I agree that no-next-method is a better name. The method I propose it
receive as an argument is the currently executing method.
I think what you mean is more precisely stated as: the method that
created the local definition of call-next-method that had no next
method. Because closures of call-next-method can be passed around
as funargs, this may not be the currently executing method at the
time NO-NEXT-METHOD is called.
Date: Mon, 2 May 88 09:33:56 CDT
From: Patrick H Dussud <DUSSUD@Jenner.csc.ti.com>
I think the concept of NO-NEXT-METHOD is fine. I don't have any
opinions about the method argument. I'd like to see David's objection
to it.
I withdraw my objection now that I understand what the argument is.
Date: Mon, 02 May 88 09:00:39 -0700
From: kempf@Sun.COM
This seems like a special case of no-applicable-method....
Date: 03 May 88 1315 PDT
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>
....
These sound as if the problem is that there is no applicable method.
Date: 3 May 88 14:50 PDT
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
I think the critical issue here is that for intelligent error handling,
different arguments are necessary for NO-NEXT-METHOD and NO-APPLICABLE-METHOD.
Date: Wed, 04 May 88 08:42:20 -0700
From: kempf@Sun.COM
(defmethod no-applicable-method ((method standard-method) &rest arguments)
(error "No applicable method for CALL-NEXT-METHOD from method ~S having~
argument list ~S.~%" method arguments))
Depending on one's personal sense of programming style, this clever
trick is either a good simplification of the language by avoiding
introducing two names where one will do, or a vile pun that confuses two
concepts that should be separate. This can be seen as analogous to some
users' objection to CLOS method argument list congruence rules, on the
grounds that a single generic function ought to be usable with two
disjoint families of classes where the methods take different arguments
and that CLOS is wrong to force the programmer to choose two different
names. In any case I believe this is only an issue of naming and that
the same application programs can be written no matter which way CLOS
goes on this issue.
I have no strong opinion on this issue. My own sense of programming
style dictates that in any program I wrote, two separate generic
functions would be used. However, I think the other programming style
is a perfectly legitimate style, and I have no strong opinion which
style CLOS should adopt. I will point out however that I am unable to
think of any other cases in which CLOS has used a single generic
function specialized to two disjoint families of classes (in this case,
generic functions and methods). For example, 88-003 proposes separate
class-name, slot-description-name, and generic-function-name functions,
rather than a single function called metaobject-name, standard-object-name,
object-name, or name.
∂04-May-88 1152 Common-Lisp-Object-System-mailer No-applicable-method
To: common-lisp-object-system@SAIL.Stanford.EDU
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>
I think Kempf's solution is not a pun, but Moon's reaction to it has the
same motivation that LGD and I have had to try to specify what the various
generic functions in CLOS are supposed to do (including the sorts of
arguments) to try to limit the creation of disjoint sets of methods,
as Kempf's technique does.
In any event, I found the combination of Danny's and Jonl's arguments
persuasive. That is, CALL-NEXT-METHOD errors could be so obscure
that it deserves its own generic function.
-rpg-
∂04-May-88 1257 Common-Lisp-Object-System-mailer Initialization
To: common-lisp-object-system@SAIL.Stanford.EDU
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>
I've reworked the material Sonya wrote to try to make the presentation
a little easier to understand. I hope that tomorrow I will be able to
put chapter 1 out on SAIL for Moon and Sonya to check for bugs. (It's
only Objection Creation and the updating/reinitialization sections, which
are now all together).
While reworking the material it occurred to me that there are some problems
with the naming of the generic functions. I like the names
update-instance-for-redefined-class and update-instance-for-different-class.
I don't like the name initialize-instance for the generic function that does
what initialize-instance currently does.
What initialize-instance really does it to fill the slots of an instance
according to the initargs and the initforms that it is supplied. When
something is initialized, then it is either given a set of initial values
at the beginning of a program or it is restored to a fresh state. (This is
according to the Random House Second Edition, whose authors know about
computers). In our case we call this function on fresh instances, on munged
instances, and on instance we're altering to conform to different class
definitions.
Furthermore, the generic function initialize-new-instance seems to me to
be the corresponding function to reinitialize-instance. Therefore, I
suggest we rename initialize-new-instance to be initialize-instance, and
we rename initialize-instance to be something like fill-and-initialize-slots.
Now, another possibility is to break up the current initialize-instance
into two pieces: one that fills slots using initargs and another that
fills unbound slots using initforms. Then we can name them fill-slots and
initialize-slots. We can pull the usual trick of stating that update...
and all those guys are implemented as if they called these two functions
but that optimizations are allowed (and method definitions would undo
those optimizations).
On the other hand, it's all pretty complicated already.
-rpg-
∂04-May-88 1355 Common-Lisp-Object-System-mailer Initialization
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 4 May 88 13:55:33 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 398008; Wed 4-May-88 16:55:23 EDT
Date: Wed, 4 May 88 16:54 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Initialization
To: common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: The message of 4 May 88 15:57 EDT from Dick Gabriel <RPG@SAIL.Stanford.EDU>
Message-ID: <19880504205442.6.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: 04 May 88 1257 PDT
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>
....the generic function initialize-new-instance seems to me to
be the corresponding function to reinitialize-instance. Therefore, I
suggest we rename initialize-new-instance to be initialize-instance, and
we rename initialize-instance to be something like fill-and-initialize-slots.
I think we went around this once before. While I agree that the present
proposed names are confusing, anything that names (the proposed new)
initialize-instance a name with "slots" in it is not going to work, because
it doesn't only deal with slots. User-defined methods for (the new)
initialize-instance can do all sorts of initialization, having no more or
less to do with slots than user-defined methods for initialize-new-instance.
The distinction is not whether we're doing the slots or not, but whether this
is only for new instances or for all kinds of initialization.
I'd still like to see less confusing names, but it seems to be awfully
hard to think them up. Probably a sign that the whole structure is too
complicated, but it seems to be awfully hard to think of how to simplify
it without breaking everything.
Now, another possibility is to break up the current initialize-instance
into two pieces: one that fills slots using initargs and another that
fills unbound slots using initforms. Then we can name them fill-slots and
initialize-slots.
I think we want around this one once before, too.
∂04-May-88 1419 Common-Lisp-Object-System-mailer Re: Sun Opposition To Chapter 3 Hereby Tendered
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 4 May 88 14:19:04 PDT
Received: from Semillon.ms by ArpaGateway.ms ; 04 MAY 88 14:15:08 PDT
Date: Wed, 4 May 88 14:14 PDT
From: Gregor.pa@Xerox.COM
Subject: Re: Sun Opposition To Chapter 3 Hereby Tendered
To: kempf@Sun.COM
cc: common-lisp-object-system@SAIL.STANFORD.EDU
Fcc: BD:>Gregor>mail>outgoing-mail-2.text.newest
In-Reply-To: <8804211552.AA02282@suntana.sun.com>
Message-ID: <19880504211454.8.GREGOR@PORTNOY.parc.xerox.com>
Line-fold: no
Sorry for the long delay in responding to your message. As you know, I
have had a number of private conversations with people about this, and
it has take some time to consider everyone's opinion.
I think your concerns about the state of CLOS standardization are valid.
I agree that it is important to have something solid and well understood
as soon as possible. I also believe that we have a mandate from the
user community to include a metaobject protocol. Taken together, these
imply that we must find a way to reconcile our desire not to standardize
on research with our desire to include some sort of metaobject protocol.
By talking with everyone in the group, I have developed a proposal for
how to direct our efforts to best achieve these goals. The rest of this
message outlines that proposal.
We should start by splitting chapter 3 into two parts. We can decide
what to call them later, but for now I will call them Part I and Part
II. Part I will include the material from chapter 3 that we understand
the best and about which there is the least contention. Part II will be
the material from chapter 3 that we are not yet in agreement on.
Part I will include the initialization and reinitialization protocol
for all the kernel classes, as well as the "reader" or "query" functions
for those kernel metaobjects. This corresponds to about the first
twenty pages of the existing chapter 3.
Part II will include the actual evaluator protocols. This includes the
slot access protocol, method lookup protocol, slot inheritance protocol
etc.
Our plan will be to submit a final version of Part I at the September
meeting. We will ask X3J13 to be ready to vote on it at that meeting.
In order to do that, we will need to submit a close to final version of
it at (but not much before) the June meeting. This material is well
enough understood that there shouldn't be a problem asking X3J13 to vote
on it at that time.
In the meantime, we will continue to work on Part II. We will inform
X3J13 that we intend to try and produce a final version of this material
before the January meeting. If we conclude that we can't produce such a
document for that meeting, at least we will have standardized on Part I.
If we produce such a draft, but X3J13 doesn't accept it, there will at
least be a document from which vendors who want to supply some sort of
metaobject protocol can start.
Perhaps the most important part of this proposal is that we must be sure
that our work on Part II is well grounded. In part, this means that we
should each base our contributions on implementations of similar
functionality we are familiar with. For my own part, this will mean
that I will implement whatever we develop over the summer in PCL. This
will have the benefit of debugging our ideas, and demonstrating to X3J13
that what we are proposing is implementable.
-------
∂04-May-88 1621 Common-Lisp-Object-System-mailer Re: no-next-method | no-applicable-method
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 4 May 88 16:20:55 PDT
Received: from Semillon.ms by ArpaGateway.ms ; 04 MAY 88 16:12:09 PDT
Date: Wed, 4 May 88 16:11 PDT
From: Gregor.pa@Xerox.COM
Subject: Re: no-next-method | no-applicable-method
To: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>, Dick Gabriel
<RPG@SAIL.Stanford.EDU>, kempf@Sun.COM, Jon L White
<edsel!jonl@labrea.stanford.edu>, Patrick H Dussud <DUSSUD@Jenner.csc.ti.com>
cc: common-lisp-object-system@SAIL.STANFORD.EDU, Danny Bobrow
<Bobrow.pa@Xerox.COM>
Fcc: BD:>Gregor>mail>outgoing-mail-2.text.newest
In-Reply-To: <19880504175137.5.MOON@EUPHRATES.SCRC.Symbolics.COM>,
The message of 4 May 88 11:52 PDT from Dick Gabriel
<RPG@SAIL.Stanford.EDU>,
<8805041542.AA15982@suntana.sun.com>,
<8805040712.AA23297@bhopal.lucid.com>,
<19880503223117.3.GREGOR@PORTNOY.parc.xerox.com>,
The message of 3 May 88 13:15 PDT from Dick Gabriel
<RPG@SAIL.Stanford.EDU>,
<19880503180516.1.GREGOR@PORTNOY.parc.xerox.com>,
<8805021600.AA13865@suntana.sun.com>,
<2787575636-15393416@Jenner>,
<19880429213039.5.GREGOR@PORTNOY.parc.xerox.com>
Message-ID: <19880504231146.5.GREGOR@PORTNOY.parc.xerox.com>
Line-fold: no
This message is an attempt to summarize the discussion on this issue. I
present what I believe we have decided so that it can be written up and
put into the specification.
As Moon says:
Date: Wed, 4 May 88 13:51 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
I think we are all agreed that CALL-NEXT-METHOD, when there is no next
method, should call a user specializable generic function, rather than
directly signalling an error as 88-002 says. The only point of contention
is what should the name of that generic function be.
As for people's opinion on the secondary question of what the name and
arguments of the user specializable generic function should be, most
people seem to have swung over now to the position that call-next-method
errors should have their own generic function with its own argument
list. In recent messages,
Moon says:
I have no strong opinion on this issue. My own sense of programming
style dictates that in any program I wrote, two separate generic
functions would be used.
RPG says:
In any event, I found the combination of Danny's and Jonl's arguments
persuasive. That is, CALL-NEXT-METHOD errors could be so obscure
that it deserves its own generic function.
So I believe we should have a generic function no-next-method. It
receives as arguments:
- the generic function belonging to the method (which is the
second argument)
- the method which Moon described by saying:
I think what you mean is more precisely stated as: the method that
created the local definition of call-next-method that had no next
method. Because closures of call-next-method can be passed around
as funargs, this may not be the currently executing method at the
time NO-NEXT-METHOD is called.
- and the arguments to call-next-method. These are passed with apply.
There is a system supplied method defined as if:
(defmethod no-next-method ((gf standard-generic-function)
(me standard-method)
&rest args)
(error "No next method when CALL-NEXT-METHOD is called."))
Unless there are further objections to this, I believe it can go into
chapter 1 and 2.
-------
∂04-May-88 1721 Common-Lisp-Object-System-mailer Re: symbol-class is bad name
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 4 May 88 17:21:30 PDT
Received: from Semillon.ms by ArpaGateway.ms ; 04 MAY 88 16:27:24 PDT
Date: Wed, 4 May 88 16:24 PDT
From: Gregor.pa@Xerox.COM
Subject: Re: symbol-class is bad name
To: Jon L White <edsel!jonl@labrea.stanford.edu>, Warren Harris
<harris%hplwhh@hplabs.HP.COM>, kempf@Sun.COM, Patrick H Dussud
<DUSSUD@Jenner.csc.ti.com>
cc: Dick Gabriel <RPG@SAIL.Stanford.EDU>,
common-lisp-object-system@sail.stanford.edu
Fcc: BD:>Gregor>mail>outgoing-mail-2.text.newest
In-Reply-To: <8805040633.AA23219@bhopal.lucid.com>,
<11430.578699086@hplwhh>,
<19880503180226.0.GREGOR@PORTNOY.parc.xerox.com>,
<8805021604.AA13873@suntana.sun.com>,
<2787573019-15236199@Jenner>,
<19880429213546.6.GREGOR@PORTNOY.parc.xerox.com>,
<8804301002.AA10473@bhopal.lucid.com>
Message-ID: <19880504232436.8.GREGOR@PORTNOY.parc.xerox.com>
Line-fold: no
This message attempts to summarize this issue so that we can make the
appropriate changes to chapter 1 and 2.
After looking at everyone's comments, it seems like we should replace
symbol-class with find-class.
Find-class will take an optional second argument saying whether or not
is should signal an error if there is no class with that name. The
default value of the argument will be t. If that argument is nil, and
there is no class with the given name, find-class will return nil. We
will say that the first argument to find-class must be a symbol. Others
can extend that later if they want.
cboundp and cmakunboundp will be removed. cboundp can be replaced with
(find-class <name> nil). cmakunbound can be replaced with (setf
(find-class <name>) nil).
This could be defined as follows:
(defun find-class (symbol &optional (errorp t))
(let ((class (<lookup-in-name-table> symbol)))
(cond (class class)
(errorp (error "No class named ~S." symbol))
(t nil))))
Unless there are further objections to this I propose the changes be
made to chapter 1 and 2.
-------
∂04-May-88 1836 Common-Lisp-Object-System-mailer Re: symbol-class is bad name
Received: from Score.Stanford.EDU by SAIL.Stanford.EDU with TCP; 4 May 88 18:36:23 PDT
Received: from hplabs.HP.COM ([15.255.16.7].#Internet) by SCORE.STANFORD.EDU with TCP; Wed 4 May 88 18:30:02-PDT
Received: from hplms2.HP.COM (hplms2) by hplabs.HP.COM with SMTP ; Wed, 4 May 88 16:45:09 PST
Received: from hplwhh.HPL.HP.COM (hplwhh.hpl.hp.com) by hplms2.HP.COM; Wed, 4 May 88 17:44:49 pdt
Received: from hplwhh by hplwhh.HPL.HP.COM; Wed, 4 May 88 17:43:27 pdt
To: Gregor.pa@Xerox.COM, common-lisp-object-system@sail.stanford.edu
Subject: Re: symbol-class is bad name
X-Mailer: mh6.5
In-Reply-To: Your message of Wed, 04 May 88 16:24:00 -0700.
<19880504232436.8.GREGOR@PORTNOY.parc.xerox.com>
Date: Wed, 04 May 88 17:43:25 PDT
Message-Id: <688.578796205@hplwhh>
From: Warren Harris <harris%hplwhh@hplabs.HP.COM>
How about the following change too (for consistency):
(GET-METHOD gf qualifiers specializers &optional errorp)
==> (FIND-METHOD gf qualifiers specializers &optional errorp)
(ADD-METHOD gf method) and
(REMOVE-METHOD gf method)
==> (SETF (FIND-METHOD gf qualifiers specializers &optional errorp)
method-or-nil)
Perhaps explicitly stating the qualifiers and specializers in the (SETF
FIND-METHOD) function eliminates the need for "Agreement on Parameter
Specializers and Qualifiers". Maybe this doesn't make sense if the
qualifiers and specializers are already stored in the method object itself.
Also, maybe ADD-METHOD and REMOVE-METHOD should persist for efficiency
(since you may already have a handle on the method object) but be promoted
to the meta-object level. Then (SETF FIND-METHOD) should be defined in
terms of them.
Warren
∂04-May-88 1855 Common-Lisp-Object-System-mailer Re: type slot option
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 4 May 88 18:55:15 PDT
Received: from Semillon.ms by ArpaGateway.ms ; 04 MAY 88 18:48:31 PDT
Date: Wed, 4 May 88 18:48 PDT
From: Gregor.pa@Xerox.COM
Subject: Re: type slot option
To: Jon L White <edsel!jonl@labrea.stanford.edu>, Patrick H Dussud
<DUSSUD@Jenner.csc.ti.com>, kempf@Sun.COM, Dick Gabriel <RPG@SAIL.Stanford.EDU>
cc: common-lisp-object-system@sail.stanford.edu
Fcc: BD:>Gregor>mail>outgoing-mail-2.text.newest
In-Reply-To: <19880429211514.2.GREGOR@PORTNOY.parc.xerox.com>,
<8804300852.AA10316@bhopal.lucid.com>,
<2787575884-15408314@Jenner>,
<8805021541.AA13800@suntana.sun.com>,
The message of 30 Apr 88 10:19 PDT from Dick Gabriel
<RPG@SAIL.Stanford.EDU>
Message-ID: <19880505014812.0.GREGOR@PORTNOY.parc.xerox.com>
Line-fold: no
This seems to be the most problematic of the criticisms we received.
Looking over all the mail, it seems that the best thing to do is to
leave the :type option the way it is. It might be good to add a note
making it extra clear that because of the way it is defined it cannot
be used as a semantic feature. It might also be good to clarify this
section by alluding to defstruct.
It seems clear that in our presentation to X3J13 we should point out to
them that this is a problematic issue which we `inherited' from Common
Lisp in general and defstruct in particular.
Date: Fri, 29 Apr 88 14:15 PDT
From: Gregor.pa
- leave things the way they are, but make it clear that it
is the job of the user code to enforce the type option.
Moon said:
You're right that :TYPE is a compiler optimization, not a semantic
feature. It's like the TYPE declaration in that respect. If slot
options had been defined in a syntactically consistent way (i.e.
enclosed in parentheses like class options) then the syntax of this
slot option could have been based on the syntax of DECLARE and just
possibly people would be less confused about what it means. I'm not
seriously proposing that; I'd rather eliminate the option, if we're
going to make such a large change.
Date: Sat, 30 Apr 88 01:52:48 PDT
From: Jon L White <edsel!jonl@labrea.stanford.edu>
Perhaps a reasonable way out of the situation is to "defer" it to CL's
treatment of the :type option in defstruct. If ever there is mandated
such a "mode" as I referred to for defstruct, then CLOS could follow the
same protocol.
Date: Mon, 2 May 88 09:38:04 CDT
From: Patrick H Dussud <DUSSUD@Jenner.csc.ti.com>
I think this issue is too big to be decided in this group. I wouldn't
take decision before asking the whole X3J13. In case it produces an
endless and intractable discussion, I would be in favor of turning off
this option until a concensus emerges.
Date: Mon, 02 May 88 08:41:29 -0700
From: kempf@Sun.COM
I don't think we should eliminate the :type option, but I think we
ought to make it work exactly like the defstruct :type option on
pg. 310 of CLtL.
Date: 30 Apr 88 10:19 PDT
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>
As you all recall, my original writeup of this option stated that
attempting to store an invalid type SHOULD signal an error. Moon objected
on the grounds that he did not want to have to ever check it, except when
other operations would naturally check the contents (such as during an
addition).
Thus, I never saw this as a compiler pragma only but as a semantic issue.
I would favor a redux to my original wording (yes, ``redux'' is the word I
mean).
-------
∂04-May-88 1904 Common-Lisp-Object-System-mailer Re: generic-function special form
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 4 May 88 19:04:00 PDT
Received: from Semillon.ms by ArpaGateway.ms ; 04 MAY 88 18:59:12 PDT
Date: Wed, 4 May 88 18:59 PDT
From: Gregor.pa@Xerox.COM
Subject: Re: generic-function special form
To: Dick Gabriel <RPG@SAIL.Stanford.EDU>, Patrick H Dussud
<DUSSUD@Jenner.csc.ti.com>, kempf@Sun.COM
cc: common-lisp-object-system@sail.stanford.edu
Fcc: BD:>Gregor>mail>outgoing-mail-2.text.newest
In-Reply-To: <19880429212530.4.GREGOR@PORTNOY.parc.xerox.com>,
The message of 30 Apr 88 10:19 PDT from Dick Gabriel
<RPG@SAIL.Stanford.EDU>,
<2787573500-15265067@Jenner>,
<8805021554.AA13841@suntana.sun.com>
Message-ID: <19880505015900.1.GREGOR@PORTNOY.parc.xerox.com>
Line-fold: no
There hasn't been enough conversation about this for us to converge. In
particular, Moon hasn't replied about whether or not he agrees that
generic-function efunctuates the method-function bodies contained in it.
It seems to me that generic-function is like function. It causes part
of its body to be efunctuated. It could be implemented as a macro and
have the same effect, but I don't see why that is a good idea.
To make things simpler for people who may not have the old messages
filed, here are all the messages I have on this topic:
Date: Fri, 29 Apr 88 14:25 PDT
From: Gregor.pa
One of the comments we received was:
Date: Fri, 15 Apr 88 13:43 PDT
From: David N Gray <Gray@DSG.csc.ti.com>
It is not apparent why GENERIC-FUNCTION needs to be a special form
instead of a macro.
Gregor said:
Because Common Lisp doesn't have lambda macros.
Moon said:
No, that's wrong, because GENERIC-FUNCTION is not something that can be
used inside the FUNCTION special form. In other words, GENERIC-FUNCTION
evaluates, it doesn't efunctuate. As far as I can see GENERIC-FUNCTION
could be a macro that expands into MAKE-INSTANCE <generic-function-class>
and a bunch of initargs including some that are forms that construct methods.
I think Gray is right on this one and it's a mistake in the document.
We should check with RPG, who proposed this.
Gregor said:
I am surprised to here that generic-function cannot be used inside the
function special form. It doesn't say that in the documentation, and
since the method bodies are supplied as forms, I think this must
efunctuate. It must capture the lexical scope it was used in or else
what is it worth?
Date: 30 Apr 88 10:19 PDT
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>
On GENERIC-FUNCTION special form:
It's true I proposed it to be a special form. I did that so it
would be parallel to FUNCTION. I had even imagined some #<mumble>
reader macro for it. Unlike FUNCTION, GENERIC-FUNCTION can be a macro
for MAKE-INSTANCE. In Qlisp we have a macro called QLAMBDA which is
like LAMBDA except it cannot be used inside FUNCTION etc. It turns out
to be a drag because the differences between how you can use QLAMBDA
and how you can use LAMBDA seem gratuitous. Similarly, I thought that
folks would prefer to see GENERIC-FUNCTION be as similar to FUNCTION as
possible.
GENERIC-FUNCTION as a macro can efunctuate what it needs to inside the
#'lambda's that appear inside the method-forming part of the expansion of
the macro. I can imagine people making mistakes the first time they write
this macro.
Date: Mon, 2 May 88 08:58:20 CDT
From: Patrick H Dussud <DUSSUD@Jenner.csc.ti.com>
I think that a macro will work. A macro can return a form that capture
the lexical environment if it contains lambda forms.
Date: Mon, 02 May 88 08:54:39 -0700
From: kempf@Sun.COM
Arguments on the side of making it a special form are those cited by RPG
and Gregor, namely that consistency between the way function and
generic-function work seems like a good idea (RPG's qlambda example) and
the need for capturing the lexical environment (Gregor). On the minus
side is the stated goal of Common Lisp to limit the number of special
forms and the obvious macroexpansion for generic-function.
I tend to think that generic-function should be a special form, for
the arguments cited, and because it seems like a different enough
piece of functionality to justify going beyond the goal of limiting
special forms.
-------
∂04-May-88 1932 Common-Lisp-Object-System-mailer Re: documentation slot option
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 4 May 88 19:32:31 PDT
Received: from Semillon.ms by ArpaGateway.ms ; 04 MAY 88 19:21:44 PDT
Date: Wed, 4 May 88 19:21 PDT
From: Gregor.pa@Xerox.COM
Subject: Re: documentation slot option
To: Dick Gabriel <RPG@SAIL.Stanford.EDU>, kempf@Sun.COM
cc: common-lisp-object-system@sail.stanford.edu
Fcc: BD:>Gregor>mail>outgoing-mail-2.text.newest
In-Reply-To: <19880429212048.3.GREGOR@PORTNOY.parc.xerox.com>,
The message of 30 Apr 88 10:19 PDT from Dick Gabriel
<RPG@SAIL.Stanford.EDU>,
<8805021545.AA13811@suntana.sun.com>
Message-ID: <19880505022134.2.GREGOR@PORTNOY.parc.xerox.com>
Line-fold: no
This issue caused the least excitement of all. I don't find that
surprising. No one seems to want to push for it, and no one seems
to want to push against it.
From: Gregor.pa
I am mildly opposed to this because I think documentation strings are a
joke.
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>
I have no opinion.
From: kempf@Sun.COM
I'm mildly in favor of this, but don't feel particularly strongly about it.
In a situation like this, one argument says, keep the standard small -
don't put it in. Another argument says, be responsive to criticism -
put it in.
I suggest we be responsive to criticism.
Here is a recap of what this slot option does.
This option would provide a documentation string for the automatically
generated :reader or :writer methods for the slot.
So:
(defclass foo ()
((x :reader foo-x
:reader bar-x
:writer foo-x
:documentation "the x slot stores the x position")))
would be equivalent to:
(defclass foo ()
((x)))
(defmethod foo-x ((foo foo))
"the x slot stores the x position"
(slot-value foo 'x))
(defmethod bar-x ((foo foo))
"the x slot stores the x position"
(slot-value foo 'x))
(defmethod (setf foo-x) (new-value (foo foo))
"the x slot stores the x position"
(setf (slot-value foo 'x) new-value))
-------
∂04-May-88 1945 Common-Lisp-Object-System-mailer Re: No-applicable-method
Received: from Sun.COM by SAIL.Stanford.EDU with TCP; 4 May 88 19:45:01 PDT
Received: from snail.sun.com by Sun.COM (4.0/SMI-4.0)
id AA09160; Wed, 4 May 88 19:44:16 PDT
Received: from suntana.sun.com ([192.29.43.122]) by snail.sun.com (4.0/SMI-3.2)
id AA01665; Wed, 4 May 88 16:00:21 PDT
Received: from localhost by suntana.sun.com (3.2/SMI-3.2)
id AA16694; Wed, 4 May 88 11:55:25 PDT
Message-Id: <8805041855.AA16694@suntana.sun.com>
To: Dick Gabriel <RPG@SAIL.Stanford.EDU>
Cc: common-lisp-object-system@SAIL.Stanford.EDU
Subject: Re: No-applicable-method
In-Reply-To: Your message of 04 May 88 11:52:00 -0700.
<8805041858.AA01867@Sun.COM>
Date: Wed, 04 May 88 11:55:23 -0700
From: kempf@Sun.COM
Guess I'm outvoted then, vile pun or no vile pun. NO-NEXT-METHOD it is.
jak
∂04-May-88 2302 Common-Lisp-Object-System-mailer Initialization Names
To: common-lisp-object-system@SAIL.Stanford.EDU
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>
It seems that the confusion between initialize-new-instance and
initialize-instance is too much to bear. How about renaming
as follows:
initialize-new-instance => initialize-instance
initialize-instance => shared-initialize
-rpg-
∂05-May-88 0702 Common-Lisp-Object-System-mailer Initialization Names
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 5 May 88 07:02:04 PDT
Received: from JUNCO.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 398370; Thu 5-May-88 10:01:47 EDT
Date: Thu, 5 May 88 10:01 EDT
From: Sonya E. Keene <skeene@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Initialization Names
To: RPG@SAIL.STANFORD.EDU
cc: common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: The message of 5 May 88 02:02 EDT from Dick Gabriel <RPG@SAIL.Stanford.EDU>
Message-ID: <19880505140136.7.SKEENE@JUNCO.SCRC.Symbolics.COM>
Date: 04 May 88 2302 PDT
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>
It seems that the confusion between initialize-new-instance and
initialize-instance is too much to bear. How about renaming
as follows:
initialize-new-instance => initialize-instance
initialize-instance => shared-initialize
-rpg-
I vote in favor of these names. Adding "shared" to the name will clear
up a lot of confusion.
∂05-May-88 1048 Common-Lisp-Object-System-mailer Initialization Names
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 5 May 88 10:45:21 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 398604; Thu 5-May-88 13:45:12 EDT
Date: Thu, 5 May 88 13:45 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Initialization Names
To: common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: <19880505140136.7.SKEENE@JUNCO.SCRC.Symbolics.COM>
Message-ID: <19880505174501.4.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Thu, 5 May 88 10:01 EDT
From: Sonya E. Keene <skeene@STONY-BROOK.SCRC.Symbolics.COM>
Date: 04 May 88 2302 PDT
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>
It seems that the confusion between initialize-new-instance and
initialize-instance is too much to bear. How about renaming
as follows:
initialize-new-instance => initialize-instance
initialize-instance => shared-initialize
I vote in favor of these names. Adding "shared" to the name will clear
up a lot of confusion.
Is there a risk of programmers thinking shared-initialize has something
to do with shared slots? (I checked that 88-002 really uses the term
"shared slot" since I couldn't remember if we had switched to a different
term or not.) Would "common" be better than "shared", or would that
stimulate confusion with the "common" in "Common Lisp"?
∂05-May-88 1101 Common-Lisp-Object-System-mailer Re: Initialization Names
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 5 May 88 11:01:49 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 05 MAY 88 10:54:37 PDT
Date: Thu, 5 May 88 10:25 PDT
From: Gregor.pa@Xerox.COM
Subject: Re: Initialization Names
To: Dick Gabriel <RPG@SAIL.Stanford.EDU>
cc: common-lisp-object-system@SAIL.Stanford.EDU
Fcc: BD:>Gregor>mail>outgoing-mail-2.text.newest
In-Reply-To: The message of 4 May 88 23:02 PDT from Dick Gabriel
<RPG@SAIL.Stanford.EDU>
Message-ID: <19880505172559.3.GREGOR@PORTNOY.parc.xerox.com>
Line-fold: no
Date: 04 May 88 23:02 PDT
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>
It seems that the confusion between initialize-new-instance and
initialize-instance is too much to bear. How about renaming
as follows:
initialize-new-instance => initialize-instance
initialize-instance => shared-initialize
I like these names.
-------
∂05-May-88 1111 Common-Lisp-Object-System-mailer Initialization-names
To: common-lisp-object-system@SAIL.Stanford.EDU
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>
The main confusion about initialize-instance is that it sounds as if it is
the main function rather than the helper function (that does all the
interesting work). There is a traditional solution to the naming problem
for such cases:
initialize-new-instance => initialize-instance
initialize-instance => initialize-instance-1
-rpg-
∂05-May-88 1556 Common-Lisp-Object-System-mailer Re: Initialization Names
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 5 May 88 15:55:44 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 05 MAY 88 15:48:09 PDT
Date: 5 May 88 15:48 PDT
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Re: Initialization Names
To: common-lisp-object-system@SAIL.STANFORD.EDU
Message-ID: <880505-154809-2896@Xerox>
Date: 04 May 88 23:02 PDT
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>
It seems that the confusion between initialize-new-instance and
initialize-instance is too much to bear. How about renaming
as follows:
initialize-new-instance => initialize-instance
initialize-instance => shared-initialize
These are fine with me. Would shared-set-state or shared-setup be better to
indicate more that this generic fucntion can be called at other than
initialization time?
∂05-May-88 1746 Common-Lisp-Object-System-mailer Re: type slot option
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 5 May 88 17:46:47 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 399120; Thu 5-May-88 20:46:39 EDT
Date: Thu, 5 May 88 20:46 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: type slot option
To: common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: <19880505014812.0.GREGOR@PORTNOY.parc.xerox.com>
Message-ID: <19880506004632.4.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Wed, 4 May 88 18:48 PDT
From: Gregor.pa@Xerox.COM
Looking over all the mail, it seems that the best thing to do is to
leave the :type option the way it is.
I agree.
Date: Mon, 02 May 88 08:41:29 -0700
From: kempf@Sun.COM
I don't think we should eliminate the :type option, but I think we
ought to make it work exactly like the defstruct :type option on
pg. 310 of CLtL.
I believe that was the intention of the way :type is now, although
the CLtL writeup is sufficiently unclear that it's difficult to be sure.
Date: 30 Apr 88 10:19 PDT
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>
As you all recall, my original writeup of this option stated that
attempting to store an invalid type SHOULD signal an error. Moon objected
on the grounds that he did not want to have to ever check it, except when
other operations would naturally check the contents (such as during an
addition).
Thus, I never saw this as a compiler pragma only but as a semantic issue.
I would favor a redux to my original wording (yes, ``redux'' is the word I
mean).
I have to object to being painted as an obstructionist. My position is that
CLOS should be consistent with CL on issues such as this one that are not
specifically related to object-oriented programming. If X3J13 wants to change
Common Lisp to enforce type declarations always, or in specified circumstances,
that's fine. In the absence of that I think CLOS should remain consistent
with the imprecision of the rest of Common Lisp. Otherwise CLOS will
make Common Lisp even more chaotic than it already is.
∂05-May-88 1741 Common-Lisp-Object-System-mailer Re: documentation slot option
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 5 May 88 17:41:37 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 399114; Thu 5-May-88 20:41:26 EDT
Date: Thu, 5 May 88 20:41 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: documentation slot option
To: common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: <19880505022134.2.GREGOR@PORTNOY.parc.xerox.com>
Message-ID: <19880506004107.3.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Wed, 4 May 88 19:21 PDT
From: Gregor.pa@Xerox.COM
I suggest we be responsive to criticism.
Sure, let's put it in.
There's a bug in your example:
(defclass foo ()
((x :reader foo-x
:reader bar-x
:writer foo-x
:documentation "the x slot stores the x position")))
would be equivalent to:
(defmethod (setf foo-x) (new-value (foo foo))
"the x slot stores the x position"
(setf (slot-value foo 'x) new-value))
The :writer slot option does not stick on setf, it uses the exact name
supplied (88-002 p.2-25), so the slot option should be :writer (foo-x).
∂05-May-88 1759 Common-Lisp-Object-System-mailer Re: symbol-class is bad name
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 5 May 88 17:59:01 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 399132; Thu 5-May-88 20:58:53 EDT
Date: Thu, 5 May 88 20:58 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: symbol-class is bad name
To: common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: <19880504232436.8.GREGOR@PORTNOY.parc.xerox.com>,
<688.578796205@hplwhh>
Message-ID: <19880506005847.5.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Wed, 4 May 88 16:24 PDT
From: Gregor.pa@Xerox.COM
After looking at everyone's comments, it seems like we should replace
symbol-class with find-class.
Agreed (including your details, deleted from this reply).
find-class needs to take an optional environment (third argument) for
the same reason that symbol-class did (88-002 p.2-78).
Date: Wed, 04 May 88 17:43:25 PDT
From: Warren Harris <harris%hplwhh@hplabs.HP.COM>
How about the following change too (for consistency):
(GET-METHOD gf qualifiers specializers &optional errorp)
==> (FIND-METHOD gf qualifiers specializers &optional errorp)
(ADD-METHOD gf method) and
(REMOVE-METHOD gf method)
==> (SETF (FIND-METHOD gf qualifiers specializers &optional errorp)
method-or-nil)
I agree with this suggestion.
Also, maybe ADD-METHOD and REMOVE-METHOD should persist for efficiency
(since you may already have a handle on the method object) but be promoted
to the meta-object level. Then (SETF FIND-METHOD) should be defined in
terms of them.
ADD-METHOD and REMOVE-METHOD should persist, but not for efficiency.
ADD-METHOD and REMOVE-METHOD are part of the anonymous-object layer,
whereas (SETF FIND-METHOD) is part of a layer for methods that is
analogous to the named-object layer for classes, generic functions,
and method combinations. I say "analogous" because methods don't
exactly have names in the same way that classes do.
∂05-May-88 1803 Common-Lisp-Object-System-mailer Re: Sun Opposition To Chapter 3 Hereby Tendered
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 5 May 88 18:03:27 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 399106; Thu 5-May-88 20:26:41 EDT
Date: Thu, 5 May 88 20:26 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: Sun Opposition To Chapter 3 Hereby Tendered
To: common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: <19880504211454.8.GREGOR@PORTNOY.parc.xerox.com>
Message-ID: <19880506002634.2.MOON@EUPHRATES.SCRC.Symbolics.COM>
I think Gregor's response to Jim's message is a good plan and
we should follow it. I'd like to thank Jim for providing the
impulse to get our heads out of the technical details and realize
that we were moving towards making the mistake of standardizing
on too much, too soon. Doing the well understood part of meta
objects first, with the more complex part to follow later, seems
just right to me.
∂05-May-88 1813 Common-Lisp-Object-System-mailer Re: generic-function special form
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 5 May 88 18:13:19 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 399146; Thu 5-May-88 21:13:10 EDT
Date: Thu, 5 May 88 21:13 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: generic-function special form
To: common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: <19880505015900.1.GREGOR@PORTNOY.parc.xerox.com>
Message-ID: <19880506011303.6.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Wed, 4 May 88 18:59 PDT
From: Gregor.pa@Xerox.COM
There hasn't been enough conversation about this for us to converge. In
particular, Moon hasn't replied about whether or not he agrees that
generic-function efunctuates the method-function bodies contained in it.
I'm more than a little behind on mail these days, and your question was
hard to answer since we're not communicating on the same wavelength, or
something. See below.
It seems to me that generic-function is like function. It causes part
of its body to be efunctuated. It could be implemented as a macro and
have the same effect, but I don't see why that is a good idea.
I don't understand why the fact that GENERIC-FUNCTION is like FUNCTION has
any bearing on the choice of whether it's documented as a macro or as a
special form. The (somewhat quixotic in my opinion) grounds for making
this decision in Common Lisp are documented in CLtL p.57 paragraph 2.
I see no reason why a program understanding program would need to have
special knowledge of GENERIC-FUNCTION; as far as I can see, GENERIC-FUNCTION
can be macro expanded into a combination of functions and existing special
forms.
Date: Fri, 29 Apr 88 14:25 PDT
From: Gregor.pa
I am surprised to here that generic-function cannot be used inside the
function special form. It doesn't say that in the documentation, and
since the method bodies are supplied as forms, I think this must
efunctuate. It must capture the lexical scope it was used in or else
what is it worth?
You didn't really think (FUNCTION (GENERIC-FUNCTION ...)) was any more
meaningful than (FUNCTION (MAKE-INSTANCE ...)), did you? To pass a
generic function as an argument, one writes (GENERIC-FUNCTION ...), it
isn't necessary to put FUNCTION in front of it. The documentation doesn't
have to say that a function or macro cannot be used inside the FUNCTION
special form, since LAMBDA is the only word that can be used that way.
Yes, the method bodies of GENERIC-FUNCTION capture the lexical scope
they are defined in, I believe (88-002 doesn't actually say). If we
believe what 88-003 p.42 says (I think we've changed our mind a little
since this document was printed), then GENERIC-FUNCTION accomplishes
this lexical capturing with the METHOD-LAMBDA word. In any case,
GENERIC-FUNCTION does it the same way that DEFMETHOD does.
Date: 30 Apr 88 10:19 PDT
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>
Similarly, I thought that
folks would prefer to see GENERIC-FUNCTION be as similar to FUNCTION as
possible.
Right. I think Gregor's confusion was that he thought GENERIC-FUNCTION
should be as similar to LAMBDA as possible.
Unless I'm missing something, none of the arguments actually speak to the
issue of whether GENERIC-FUNCTION should be a macro or a special form.
Note that this decision has no semantic effect other than on code analyzing
programs. I hate to spend any more time on this issue, however it seems
to me that our response to the criticism must be either "you're right,
we've changed it to a macro" or "we don't have time to think about this
so we left it alone." I don't see a viable response of "you're wrong
for the following reason."
∂05-May-88 2005 Common-Lisp-Object-System-mailer Re: no-next-method | no-applicable-method
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 5 May 88 20:05:02 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 399149; Thu 5-May-88 21:15:25 EDT
Date: Thu, 5 May 88 21:15 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: no-next-method | no-applicable-method
To: common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: <19880504231146.5.GREGOR@PORTNOY.parc.xerox.com>
Message-ID: <19880506011518.7.MOON@EUPHRATES.SCRC.Symbolics.COM>
Agreed.
∂05-May-88 2005 Common-Lisp-Object-System-mailer "Written Responses" to CLOS 88-002: SETF Functions
Received: from ALDERAAN.SCRC.Symbolics.COM ([128.81.41.109]) by SAIL.Stanford.EDU with TCP; 5 May 88 20:05:48 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by ALDERAAN.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 191209; Thu 5-May-88 21:19:53 EDT
Date: Thu, 5 May 88 21:20 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: "Written Responses" to CLOS 88-002: SETF Functions
To: Jon L White <edsel!jonl@labrea.Stanford.EDU>
cc: common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: <8804280210.AA00769@bhopal.lucid.com>
Message-ID: <19880506012000.8.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Wed, 27 Apr 88 19:10:14 PDT
From: Jon L White <edsel!jonl@labrea.Stanford.EDU>
re: If X3J13 has adopted setf functions, I agree that the CLOS spec does not
need to discuss them. If X3J13 is still dithering, I think the writeup
should stay in the CLOS spec. If X3J13 has rejected setf functions, then
we have a problem.
SETF functions foundered on issues having nothing to do with function specs.
I say, "foundered", not meaning that they were rejected, but that substantial
issues were raised (mostly by Sandra Loosemore), and the discussion didn't
come to completion by the end of the day.
You missed the "Definitions Specs" presentation; there seemed to be
unanimous approval for continuing that proposal. Even if there is
continuing objection/discussion (and I don't think there will be) to the
particulars of the "setf functions" semantics, there doesn't seem to be
objections to "function specs".
I hope we're going to vote on SETF functions in June so we can get this
out of the way.
I believe that most of Sandra's objections were met by our collective
responses that day. For example, she wanted to know why their syntax
differed from that suggested by DEFSETF -- why the "new value" was the
first argument rather than the last. We replied that it is necessary to
be able to discriminate on the class of the "new value", and there is
no easy syntax for defining a method that discriminates on the last
argument rather than the first several.
This is wrong. The real reason is that Common Lisp does not provide a
lambda-list syntax for describing a function that takes a required argument
following an optional argument. Thus if new-value was the last argument,
it would be impossible for setf functions to have optional arguments, which
would be a serious hindrance. We considered schemes where the new-value
argument came between the required arguments and the optional arguments,
but rejected them as kludgey and error-prone.
However, under no circumstances can one justify leaving a "fix up" of
CL in the CLOS spec. At best, CLOS should have an appendix explaining
any non-standard assumptions about the CL language -- an appendix which
itself isn't an integral part of the spec, but only an aid for those
who are not yet familiar with other X3J13 activity.
I think the fixup of CL is only in the CLOS subcommittee report, not in
the CLOS specification as proper (which does not yet exist). However,
I like your suggestion that the CLOS subcommittee report should be
reorganized to put things that are proposed to become part of Common Lisp,
rather than part of CLOS proper, into something labeled an appendix.
∂05-May-88 2325 Common-Lisp-Object-System-mailer dealing with 1+2 comments
Received: from labrea.stanford.edu by SAIL.Stanford.EDU with TCP; 5 May 88 23:25:14 PDT
Received: by labrea.stanford.edu; Thu, 5 May 88 23:25:16 PDT
Received: from bhopal.lucid.com by edsel id AA07780g; Thu, 5 May 88 22:56:00 PDT
Received: by bhopal id AA00309g; Thu, 5 May 88 22:58:40 PDT
Date: Thu, 5 May 88 22:58:40 PDT
From: Jon L White <edsel!jonl@labrea.stanford.edu>
Message-Id: <8805060558.AA00309@bhopal.lucid.com>
To: Gregor.pa@xerox.com
Cc: common-lisp-object-system@sail.stanford.edu
Subject: dealing with 1+2 comments
You've done a good job organizing replies to the "Written Responses to
CLOS 88-002". One item, howver, hasn't appeared in the mails recently
and I wonder how it will be handled: Beckerle's forwarding of a criticism
that CLOS doesn't offer "information hiding".
Several replies seemed to contradict one another about whether something
was hard or not, and what *really* was at issue, but I don't remember a
coherent reply emerging.
Since this is a rather high-level (or "fundamental" if you will) question,
it calls for a "high level" reply. To me, the overriding factor is that
CLOS is a descendent of SmallTalk; and both its direct ancestors -- LOOPS
and FLAVORS -- were descendents of SmallTalk.
Notwithstanding the problems that Wegner's paper at the last OOPSLA
provoked, I would say that here are two major, opposing object-oriented
paradigms around -- the Smalltalk class-like ones with inheritance, and
the Actor prototype-like ones with delegation -- and CLOS is definitely of
the SmallTalk persuasion. This particular aspect of SmallTalk -- the
openness of class inheritance, as opposed to the guarded "encapsulation"
implicit in actors -- is deeply ingrained, and to amend it would require
more research (which might not even then reach a satisfactory conclusion).
I think it is enough that CLOS took on multiple inheritance, and at long
last(!) has come up with a consensus on how to make it work. It certainly
is different than multiple inheritance in many other OO systems -- where
features inherited from two different ancestors may be "adjoined" rather
than "unified", and where method-combination is a perversion.
Thus, in my view, the presence of Flavor-like multiple-inheritance
and the absence of special encapsulation mechanisms means that CLOS
has deviated from its spiritual roots just enough to fit the current
needs of the Common Lisp community.
-- JonL --
∂06-May-88 0933 Common-Lisp-Object-System-mailer Re: Sun Opposition To Chapter 3 Hereby Tendered
Received: from Sun.COM by SAIL.Stanford.EDU with TCP; 6 May 88 09:33:19 PDT
Received: from snail.sun.com by Sun.COM (4.0/SMI-4.0)
id AA07272; Fri, 6 May 88 09:32:32 PDT
Received: from suntana.sun.com by snail.sun.com (4.0/SMI-3.2)
id AA19333; Fri, 6 May 88 09:30:38 PDT
Received: from localhost by suntana.sun.com (3.2/SMI-3.2)
id AA19952; Fri, 6 May 88 09:24:46 PDT
Message-Id: <8805061624.AA19952@suntana.sun.com>
To: Gregor.pa@Xerox.COM
Cc: common-lisp-object-system@SAIL.STANFORD.EDU
Subject: Re: Sun Opposition To Chapter 3 Hereby Tendered
In-Reply-To: Your message of Wed, 04 May 88 14:14:00 -0700.
<19880504211454.8.GREGOR@PORTNOY.parc.xerox.com>
Date: Fri, 06 May 88 09:24:43 -0700
From: kempf@Sun.COM
I support this plan for further progress on the metaobject protocol.
I think it is important that the portable PCL implementation
of Chapters 1 and 2 and the agreed upon part of Chapter 3
be completed as quickly as possible. Not only will this
allow vendors to start folding it into their products soon, so users other
than universities and research institutes can start using
it, but also it may uncover important design issues for the metaobject
protocol which may need to be addressed in further discussions. These design
issues may not be fully evident without a guiding implementation.
Thanks for your attempt to get further planning on the metaobject protocol
design procedure resolved.
∂06-May-88 0950 Common-Lisp-Object-System-mailer Re: Reinitialization: check-initargs
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 6 May 88 09:50:36 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 399596; Fri 6-May-88 12:50:30 EDT
Date: Fri, 6 May 88 12:50 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: Reinitialization: check-initargs
To: Common-Lisp-Object-System@SAIL.STANFORD.EDU
In-Reply-To: <880429-190758-1574@Xerox>
Message-ID: <19880506165010.6.MOON@EUPHRATES.SCRC.Symbolics.COM>
There hasn't been any more mail, so I suggest we go with this.
Anyone who objects should do so soon, right?
Note that part of what Danny is proposing here is to eliminate
the special-purpose function check-initargs, which was only for
initialization arguments, and replace it with a general purpose
function check-keyword-arguments that can be used in any situation
involving multiple generic functions accepting a common set of
keyword arguments. Initialization arguments are probably the only
such situation among the predefined functions of CLOS, but users
might define similar protocols in their own programs.
Sonya suggests that since this is a general purpose function, it
should be written up in chapter 2. I agree. The implementation
of this function involves calling chapter 3 functions, but callers
of the function don't need to understand the implementation.
Date: 29 Apr 88 19:07 PDT
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
check-keyword-arguments keyword-arguments
generic-functions-and-arguments
&optional extra-allowed-keywords
keyword-arguments is a p-list of keyword arguments to be passed to the
generic-functions in generic-functions-and-arguments.
generic-functions-and-arguments is a list of lists, each containing a generic
function followed by a list of the required arguments that can select
appropriate methods.
extra-allowed-keywords is a list of additional allowed keywords.
make instance would call check-keyword-arguments this way
(defmethod make-instance ((class standard-class) &rest initargs)
(setq initargs (default-initargs class initargs))
(let ((proto (class-prototype class)))
(unless (check-keyword-arguments
initargs
(list (list #'allocate-instance class)
(list #'initialize-instance proto nil)
(list #'initialize-new-instance proto))
(class-slot-initargs class))
(error "illegal initarg")))
.
.
.)
There remains a problem with how to report an error. Danny proposes
that check-keyword-arguments simply returns t or nil, and the caller
must report the error. As you can see from the above example, that
tends to result in a poor error message, since the caller has no easy
way to find out which initarg(s) is/are invalid. On the other hand,
if check-keyword-arguments reports the error itself, it has no way
to find the context; it could say ":FOO is an invalid argument" but
it could not say ":FOO is an invalid initialization argument for the
class MUMBLE".
One way out of this would be for check-keyword-arguments to report
the error, with the caller supplying an additional argument that is
a string included in the error message to provide context.
I believe a more correct solution is to use the condition handling
system that has been proposed for Common Lisp but not yet adopted.
check-keyword-arguments should report the error itself, using a
specific condition with a name like invalid-keyword-arguments.
Callers that wish to supply additional context should use
HANDLER-BIND to capture the condition and resignal a condition
that encapsulates the original one and reports an error message
combining information from the two sources. The immediate implication
for CLOS is that check-keyword-arguments should signal the error
itself, and the call in MAKE-INSTANCE should ignore the returned
value. We can omit the potential use of HANDLER-BIND by MAKE-INSTANCE
from the CLOS spec. The returned value of check-keyword-arguments
should be documented to be the first argument.
As for the check-keyword-arguments on page 60 of Chapter 3, it is the one that
is misnamed. It should be called something more like
check-method-keyword-arguments.
Okay.
∂06-May-88 1030 Common-Lisp-Object-System-mailer Re: Reinitialization: check-initargs
Received: from Sun.COM by SAIL.Stanford.EDU with TCP; 6 May 88 10:30:17 PDT
Received: from snail.sun.com by Sun.COM (4.0/SMI-4.0)
id AA08116; Fri, 6 May 88 10:27:39 PDT
Received: from suntana.sun.com by snail.sun.com (4.0/SMI-3.2)
id AA21705; Fri, 6 May 88 10:25:57 PDT
Received: from localhost by suntana.sun.com (3.2/SMI-3.2)
id AA20069; Fri, 6 May 88 10:20:05 PDT
Message-Id: <8805061720.AA20069@suntana.sun.com>
To: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Cc: Common-Lisp-Object-System@SAIL.STANFORD.EDU
Subject: Re: Reinitialization: check-initargs
In-Reply-To: Your message of Fri, 06 May 88 12:50:00 -0400.
<19880506165010.6.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Fri, 06 May 88 10:20:03 -0700
From: kempf@Sun.COM
This looks good.
jak
∂06-May-88 1033 Common-Lisp-Object-System-mailer Re: Sun Opposition To Chapter 3 Hereby Tendered
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 6 May 88 10:33:06 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 06 MAY 88 10:29:51 PDT
Date: 6 May 88 10:29 PDT
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Re: Sun Opposition To Chapter 3 Hereby Tendered
In-reply-to: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>'s message of
Thu, 5 May 88 20:26 EDT
To: Moon@STONY-BROOK.SCRC.Symbolics.COM
cc: common-lisp-object-system@SAIL.STANFORD.EDU
Message-ID: <880506-102951-4126@Xerox>
I think Gregor's response to Jim's message is a good plan and
we should follow it. I'd like to thank Jim for providing the
impulse to get our heads out of the technical details and realize
that we were moving towards making the mistake of standardizing on
too much, too soon. Doing the well understood part of meta objects
first, with the more complex part to follow later, seems just right
to me.
I agree. I think what this does for us is to focus our attention on the things
we can obviously get right, as opposed to those that first attract us: things
that obviously need lots more work.
∂06-May-88 1033 Common-Lisp-Object-System-mailer Re: symbol-class is bad name
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 6 May 88 10:32:58 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 06 MAY 88 10:29:32 PDT
Date: 6 May 88 10:25 PDT
From: Bobrow.pa@Xerox.COM
Subject: Re: symbol-class is bad name
In-reply-to: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>'s message of
Thu, 5 May 88 20:58 EDT
To: Moon@STONY-BROOK.SCRC.Symbolics.COM
cc: common-lisp-object-system@SAIL.STANFORD.EDU
Message-ID: <880506-102932-4120@Xerox>
I basically agree with Moon's comments on FIND-CLASS that support Gregor's last
message, and and the uses of SETF. One small oversight
Date: Wed, 04 May 88 17:43:25 PDT
From: Warren Harris <harris%hplwhh@hplabs.HP.COM>
How about the following change too (for consistency):
(GET-METHOD gf qualifiers specializers &optional errorp)
==> (SETF (FIND-METHOD gf qualifiers specializers &optional errorp)
method-or-nil)
This is good. It must be noted however that an error must be signalled if
method does not agree with the qualifiers and specializers provided.
∂06-May-88 1336 Common-Lisp-Object-System-mailer Plan
To: common-lisp-object-system@SAIL.Stanford.EDU
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>
The following are changes LGD and I intend to make to chapters 1 and
2 unless we hear to the contrary by tuesday:
1. symbol-class => find-class (function)
cboundp, cmakunbound flushed
Find-class will take an optional second argument saying whether
or not is should signal an error if there is no class with that
name. The default value of the argument will be t. If that
argument is nil, and there is no class with the given name,
find-class will return nil. We will say that the first
argument to find-class must be a symbol. Others can extend
that later if they want.
cboundp and cmakunboundp will be removed. cboundp can be
replaced with (find-class <name> nil). cmakunbound can be
replaced with (setf (find-class <name>) nil).
2. The following generic function name changes will be made:
initialize-new-instance => initialize-instance
initialize-instance => shared-initialize
3. :documenatation slot option will added.
Here is a recap of what this slot option does.
This option would provide a documentation string for the
automatically generated :reader or :writer methods for the
slot.
So:
(defclass foo ()
((x :reader foo-x
:reader bar-x
:writer (setf foo-x)
:documentation "the x slot stores the x position")))
would be equivalent to:
(defclass foo ()
((x)))
(defmethod foo-x ((foo foo))
"the x slot stores the x position"
(slot-value foo 'x))
(defmethod bar-x ((foo foo))
"the x slot stores the x position"
(slot-value foo 'x))
(defmethod (setf foo-x) (new-value (foo foo))
"the x slot stores the x position"
(setf (slot-value foo 'x) new-value))
4. NO-NEXT-METHOD will be added.
5. GENERIC-FUNCTION will become a macro.
6. CHECK-KEYWORD-ARGUMENTS (function) will be added.
Note that part of what Danny is proposing here is to eliminate
the special-purpose function check-initargs, which was only for
initialization arguments, and replace it with a general purpose
function check-keyword-arguments that can be used in any
situation involving multiple generic functions accepting a
common set of keyword arguments. Initialization arguments are
probably the only such situation among the predefined functions
of CLOS, but users might define similar protocols in their own
programs.
Sonya suggests that since this is a general purpose function,
it should be written up in chapter 2. I agree. The
implementation of this function involves calling chapter 3
functions, but callers of the function don't need to understand
the implementation.
check-keyword-arguments keyword-arguments
generic-functions-and-arguments
&optional extra-allowed-keywords
keyword-arguments is a p-list of keyword arguments to be passed
to the generic-functions in generic-functions-and-arguments.
generic-functions-and-arguments is a list of lists, each
containing a generic function followed by a list of the
required arguments that can select appropriate methods.
extra-allowed-keywords is a list of additional allowed keywords.
make instance would call check-keyword-arguments this way
(defmethod make-instance ((class standard-class) &rest initargs)
(setq initargs (default-initargs class initargs))
(let ((proto (class-prototype class)))
(check-keyword-arguments
initargs
(list (list #'allocate-instance class)
(list #'initialize-instance proto nil)
(list #'initialize-new-instance proto))
(class-slot-initargs class)))
.
.
.)
check-keyword-arguments should signal the error itself, and the
call in MAKE-INSTANCE should ignore the returned value.
As for the check-keyword-arguments on page 60 of Chapter 3, it
is the one that is misnamed. It should be called something
more like check-method-keyword-arguments.
7. CHECK-INITARGS will be flushed.
-rpg-
∂06-May-88 1434 Common-Lisp-Object-System-mailer Re: Plan
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 6 May 88 14:34:40 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 06 MAY 88 14:27:53 PDT
Date: 6 May 88 14:27 PDT
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Re: Plan
In-reply-to: Dick Gabriel <RPG@SAIL.Stanford.EDU>'s message of 06 May 88 13:36
PDT
To: RPG@SAIL.Stanford.EDU
cc: common-lisp-object-system@SAIL.Stanford.EDU
Message-ID: <880506-142753-4692@Xerox>
Sounds good.
Remember that find-class must take an optional environment argument.
(defun find-class (name &optional no-error environment) ...)
What about the suggestion about get-method ==> find-method ?
∂06-May-88 1455 Common-Lisp-Object-System-mailer Plan Comments
To: common-lisp-object-system@SAIL.Stanford.EDU
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>
Danny writes:
``Remember that find-class must take an optional environment argument.
(defun find-class (name &optional no-error environment) ...)''
Yep, that's my plan message.
Danny again:
``What about the suggestion about get-method ==> find-method ?''
The criticism that there might be cases when you have the method in
hand that you want to flush from a generic function is one to consider.
Until that's thought through I'm waiting on this proposed change. Hoever, I
like the general idea behind that proposed change.
-rpg-
∂06-May-88 2022 Common-Lisp-Object-System-mailer Plan Comments
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 6 May 88 20:22:31 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 399991; Fri 6-May-88 23:15:14 EDT
Date: Fri, 6 May 88 23:15 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Plan Comments
To: common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: The message of 6 May 88 17:55 EDT from Dick Gabriel <RPG@SAIL.Stanford.EDU>
Message-ID: <19880507031506.2.MOON@EUPHRATES.SCRC.Symbolics.COM>
The plan looks fine to me, with Danny's corrections.
Date: 06 May 88 1455 PDT
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>
Danny writes:
``Remember that find-class must take an optional environment argument.
(defun find-class (name &optional no-error environment) ...)''
Yep, that's my plan message.
??. The copy of your plan message I received didn't say anything about
a third argument.
BTW I disagree with Danny's tacit suggestion here to change
&optional (error-p t) to &optional (no-error nil). Our experience
is that people get very confused if the error-p arguments aren't
all the same sense.
Danny again:
``What about the suggestion about get-method ==> find-method ?''
The criticism that there might be cases when you have the method in
hand that you want to flush from a generic function is one to consider.
Until that's thought through I'm waiting on this proposed change.
I don't think I understand this comment. If what you mean is that
(setf (find-method ...) nil) can't replace everything that remove-method
can do, I agree but I thought the proposal was to have both of them.
∂06-May-88 2031 Common-Lisp-Object-System-mailer "Written Responses" to CLOS 88-002: SETF Functions
Received: from labrea.stanford.edu by SAIL.Stanford.EDU with TCP; 6 May 88 20:31:19 PDT
Received: by labrea.stanford.edu; Fri, 6 May 88 20:31:27 PDT
Received: from bhopal.lucid.com by edsel id AA12586g; Fri, 6 May 88 20:14:47 PDT
Received: by bhopal id AA04387g; Fri, 6 May 88 20:17:30 PDT
Date: Fri, 6 May 88 20:17:30 PDT
From: Jon L White <edsel!jonl@labrea.stanford.edu>
Message-Id: <8805070317.AA04387@bhopal.lucid.com>
To: Moon@stony-brook.scrc.symbolics.com
Cc: common-lisp-object-system@sail.stanford.edu
In-Reply-To: David A. Moon's message of Thu, 5 May 88 21:20 EDT <19880506012000.8.MOON@EUPHRATES.SCRC.Symbolics.COM>
Subject: "Written Responses" to CLOS 88-002: SETF Functions
re: . . . Thus if new-value was the last argument,
it would be impossible for setf functions to have optional arguments, which
would be a serious hindrance. We considered schemes where the new-value
argument came between the required arguments and the optional arguments,
but rejected them as kludgey and error-prone.
Maybe we all "bought off" on that theory that one might need to specialize
on the "newvalue" argument; but if that really isn't sufficient grounds
for the incompatible change ("newvalue" argument being first rather than
last, such as defsetf would do, and such as Symbolic's setf functions do),
then perhaps more work needs to be put into the cl-cleanup proposal.
In fact, there seem to be a couple of lacunae in the motivation for "SETF
functions", as opposed to "function specs". Not only is there this issue
of why the difference in order of arguments from DEFSETF style, but it
needs to be stated somewhere that under this change no macroexpansion of
a form like (SETF (<non-special-form>) ...) will every fail -- there will
always be an alleged "setf function" that might be later defined to supply
the need; and the only error a user might ever see will be something like
"undefined function" when he actually tries to call it (or, "called, but
not defined" when the file is compiled).
These criticisms where discussed briefly very late in the day at the last
x3j13 meeting, and there were more that I can't remember; try asking
Sondra Loosemore about them. Maybe you could take a stab at fixing up
the cl-cleanup proposal?
-- JonL --
∂07-May-88 1106 Common-Lisp-Object-System-mailer Plan Comments
To: common-lisp-object-system@SAIL.Stanford.EDU
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>
FIND-CLASS will take 1 required and two optional arguments, the first
optional (errorp) will default to t.
I had understood the proposal to be to flush remove-method. I've modified
the plan adding an eigth step:
8. get-method => find-method.
(setf (find-method ...) ...) works. Remove-method remains.
Is this right?
-rpg-
∂07-May-88 1111 RPG Question about discarded slots
∂06-May-88 2022 Moon@STONY-BROOK.SCRC.Symbolics.COM Question about discarded slots
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 6 May 88 20:22:27 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 399988; Fri 6-May-88 23:06:39 EDT
Date: Fri, 6 May 88 23:06 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Question about discarded slots
To: Dick Gabriel <RPG@SAIL.STANFORD.EDU>
In-Reply-To: The message of 6 May 88 15:45 EDT from Dick Gabriel <RPG@SAIL.Stanford.EDU>
Message-ID: <19880507030629.1.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: 06 May 88 1245 PDT
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>
In the section on redefining classes it says:
``The generic function {\bf update-instance-for-redefined-class} takes
four required arguments: the instance being updated after it has
undergone the first step, a list of the names of slots that were added,
a list of the names of slots that were discarded, and a property list
containing the slot names and values of slots that were discarded and
had values. Included among the discarded slots are slots that were
local in the old class and that are shared in the new class.''
Are slots that were shared in the old class and local in the new class
among the discarded slots (third argument)? Are they among the added
slots (second argument)?
Neither. See the second paragraph (first complete one) in p.1-47 of
the draft I printed out yesterday (the last one you edited that I know
of, so you probably have a copy with identical pagination).
moon/su
Discarded Slots
Your note indicates that you read (present tense) the spec the same as I
do on this point. My real question is whether you think that the document
is clear enough on this point. I worry about people having to go through
excessively long chains of reasoning to understand some of these things,
and as I spend more time staring at it, I worry more about this.
-rpg-
∂09-May-88 0859 Common-Lisp-Object-System-mailer Plan Comments
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 9 May 88 08:59:11 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 400610; Mon 9-May-88 11:38:36 EDT
Date: Mon, 9 May 88 11:38 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Plan Comments
To: Dick Gabriel <RPG@SAIL.STANFORD.EDU>
cc: common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: The message of 7 May 88 14:06 EDT from Dick Gabriel <RPG@SAIL.Stanford.EDU>
Message-ID: <19880509153823.5.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: 07 May 88 1106 PDT
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>
FIND-CLASS will take 1 required and two optional arguments, the first
optional (errorp) will default to t.
I had understood the proposal to be to flush remove-method. I've modified
the plan adding an eigth step:
8. get-method => find-method.
(setf (find-method ...) ...) works. Remove-method remains.
Is this right?
Right or wrong depending on how your step 8 is disambiguated. My understanding
is that (setf find-method) calls add-method if its first argument is a method
and calls remove-method if its first argument is nil, and that both add-method
and remove-method remain in chapter 2.
∂09-May-88 1030 Common-Lisp-Object-System-mailer Plan Comments
To: common-lisp-object-system@SAIL.Stanford.EDU
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>
Moon writes about (setf find-method)
``Right or wrong depending on how your step 8 is disambiguated. My
understanding is that (setf find-method) calls add-method if its first
argument is a method and calls remove-method if its first argument is nil,
and that both add-method and remove-method remain in chapter 2.''
That is what I meant, so step eight is:
8. get-method => find-method.
(setf (find-method ...) ...) works. Remove-method remains.
(setf (find-method ...) <method>) calls add-method
(setf (find-method ...) nil) calls remove-method
Add-method and remove-method remain in CLOS.
∂09-May-88 1055 Common-Lisp-Object-System-mailer Re: Plan Comments
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 9 May 88 10:55:29 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 09 MAY 88 10:50:32 PDT
Date: 9 May 88 10:50 PDT
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Re: Plan Comments
In-reply-to: Dick Gabriel <RPG@SAIL.Stanford.EDU>'s message of 09 May 88 10:30
PDT
To: RPG@SAIL.Stanford.EDU
cc: common-lisp-object-system@SAIL.Stanford.EDU
Message-ID: <880509-105032-6993@Xerox>
(setf (find-method ...) <method>) calls add-method
And if there is an incompatiblity between the method and the specified
qualifiers or specializers, an error is signalled, right?
∂09-May-88 1115 Common-Lisp-Object-System-mailer (setf find-method)
To: common-lisp-object-system@SAIL.Stanford.EDU
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>
Danny writes:
`` (setf (find-method ...) <method>) calls add-method
And if there is an incompatiblity between the method and the specified
qualifiers or specializers, an error is signalled, right?''
Add-method signals an error if there is a congruence failure. I wouldn't
expect (setf find-method) to look for the error separately.
-rpg-
∂09-May-88 1131 Common-Lisp-Object-System-mailer Re: Plan Comments
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 9 May 88 11:31:47 PDT
Received: from Chardonnay.ms by ArpaGateway.ms ; 09 MAY 88 11:25:51 PDT
Date: Mon, 9 May 88 11:20 PDT
From: Gregor.pa@Xerox.COM
Subject: Re: Plan Comments
To: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
cc: Dick Gabriel <RPG@SAIL.STANFORD.EDU>,
common-lisp-object-system@SAIL.STANFORD.EDU
Fcc: BD:>Gregor>mail>outgoing-mail-2.text.newest
In-Reply-To: <19880509153823.5.MOON@EUPHRATES.SCRC.Symbolics.COM>
Message-ID: <19880509182021.9.GREGOR@PORTNOY.parc.xerox.com>
Line-fold: no
Date: Mon, 9 May 88 11:38 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Date: 07 May 88 1106 PDT
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>
FIND-CLASS will take 1 required and two optional arguments, the first
optional (errorp) will default to t.
I had understood the proposal to be to flush remove-method. I've modified
the plan adding an eigth step:
8. get-method => find-method.
(setf (find-method ...) ...) works. Remove-method remains.
Is this right?
Right or wrong depending on how your step 8 is disambiguated. My understanding
is that (setf find-method) calls add-method if its first argument is a method
and calls remove-method if its first argument is nil, and that both add-method
and remove-method remain in chapter 2.
I think that trying to make setf of find-method work is a bad idea. We
already have add-method and remove-method, they work, and are clear. I
think we are just going to end up with a kludgey sort of interface to
them if we try to make setf of find-method work.
Lets leave this out of the current draft. This kind of last minute
change which no one has a chance to think about carefully is not a good
idea.
-------
∂09-May-88 1135 Common-Lisp-Object-System-mailer (setf find-method)
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 9 May 88 11:35:14 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 400863; Mon 9-May-88 14:35:09 EDT
Date: Mon, 9 May 88 14:35 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: (setf find-method)
To: common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: The message of 9 May 88 14:15 EDT from Dick Gabriel <RPG@SAIL.Stanford.EDU>
Message-ID: <19880509183500.6.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: 09 May 88 1115 PDT
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>
Danny writes:
`` (setf (find-method ...) <method>) calls add-method
And if there is an incompatiblity between the method and the specified
qualifiers or specializers, an error is signalled, right?''
Add-method signals an error if there is a congruence failure. I wouldn't
expect (setf find-method) to look for the error separately.
No, the error that add-method is checking for is something different.
Add-method is checking arglist congruence. The checking Danny refers to
is that the copy of the qualifiers and specializers passed as explicit
arguments to (setf find-method) agree with the copy of these data stored
in slots in the method object. Add-method does not receive the
arguments that it would need to do this checking. (setf find-method)
has to check consistency of these redundant arguments itself.
∂09-May-88 1221 Common-Lisp-Object-System-mailer Re: Plan Comments
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 9 May 88 12:20:52 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 400911; Mon 9-May-88 15:20:49 EDT
Date: Mon, 9 May 88 15:20 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: Plan Comments
To: common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: <19880509182021.9.GREGOR@PORTNOY.parc.xerox.com>
Message-ID: <19880509192039.1.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Mon, 9 May 88 11:20 PDT
From: Gregor.pa@Xerox.COM
I think that trying to make setf of find-method work is a bad idea. We
already have add-method and remove-method, they work, and are clear. I
think we are just going to end up with a kludgey sort of interface to
them if we try to make setf of find-method work.
Lets leave this out of the current draft. This kind of last minute
change which no one has a chance to think about carefully is not a good
idea.
Oh mumble, you're probably right. So setf of find-class will work, but
setf of find-method won't. What about setf of find-generic-function, leave
that out too?
∂09-May-88 1221 Common-Lisp-Object-System-mailer Find-method
To: common-lisp-object-system@SAIL.Stanford.EDU
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>
Renaming get-method to find-method is ok. Now that I really
take a look at (setf find-method), I am inclined to oppose it.
The main reason is the duplication of specializers and qualifiers.
Suppose a human is using (setf find-method):
(setf (find-method ...<specializers> <qualifiers> ...)
(make-instance ... <specializers> <qualifiers> ...))
Then you have to type the specializers and qualifiers twice, and you
probably suffer an error being signaled when you blow one or the other
of the two specifications. Of course, this probably helps find bugs
by making you always look at such method definitions twice, but maybe
a programming environment can always signal an error when you define a
method using make-instance on general principles to get the same effect.
I don't see what we gain from this generality except that we can say that
in many cases, when the path of generality was available, we took it -
regardless of how pretty it was.
-rpg-
∂09-May-88 1329 Common-Lisp-Object-System-mailer Re: Find-method
Received: from ti.com by SAIL.Stanford.EDU with TCP; 9 May 88 13:29:45 PDT
Received: by ti.com id AA08454; Mon, 9 May 88 15:28:09 CDT
Received: from Jenner by tilde id AA20407; Mon, 9 May 88 15:20:15 CDT
Message-Id: <2788201047-973287@Jenner>
Date: Mon, 9 May 88 15:17:27 CDT
From: Patrick H Dussud <DUSSUD@Jenner.csc.ti.com>
To: Dick Gabriel <RPG@SAIL.STANFORD.EDU>
Cc: common-lisp-object-system@SAIL.STANFORD.EDU
Subject: Re: Find-method
In-Reply-To: Msg of 09 May 88 1221 PDT from Dick Gabriel <RPG@SAIL.STANFORD.EDU>
Date: 09 May 88 1221 PDT
From: Dick Gabriel <RPG@SAIL.STANFORD.EDU>
Subject: Find-method
Renaming get-method to find-method is ok. Now that I really
take a look at (setf find-method), I am inclined to oppose it.
The main reason is the duplication of specializers and qualifiers.
I agree with Dick and Gregor. I don't see what it it brings us, beside
yet another way to confuse people.
Patrick.
∂09-May-88 1341 Common-Lisp-Object-System-mailer Re: Find-method
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 9 May 88 13:41:02 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 09 MAY 88 13:41:04 PDT
Date: 9 May 88 13:40 PDT
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Re: Find-method
In-reply-to: Patrick H Dussud <DUSSUD@Jenner.csc.ti.com>'s message of Mon, 9 May
88 15:17:27 CDT
To: DUSSUD@Jenner.csc.ti.com
cc: RPG@SAIL.STANFORD.EDU, common-lisp-object-system@SAIL.STANFORD.EDU
Message-ID: <880509-134104-7406@Xerox>
Renaming get-method to find-method is ok. Now that I really
take a look at (setf find-method), I am inclined to oppose it.
The main reason is the duplication of specializers and qualifiers.
I agree with Dick and Gregor. I don't see what it it brings us, beside
yet another way to confuse people.
I agree too.
∂09-May-88 1520 Common-Lisp-Object-System-mailer Re: Plan Comments
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 9 May 88 15:19:55 PDT
Received: from Semillon.ms by ArpaGateway.ms ; 09 MAY 88 15:12:17 PDT
Date: Mon, 9 May 88 15:11 PDT
From: Gregor.pa@Xerox.COM
Subject: Re: Plan Comments
To: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
cc: common-lisp-object-system@SAIL.STANFORD.EDU
Fcc: BD:>Gregor>mail>outgoing-mail-2.text.newest
In-Reply-To: <19880509192039.1.MOON@EUPHRATES.SCRC.Symbolics.COM>
Message-ID: <19880509221155.1.GREGOR@PORTNOY.parc.xerox.com>
Line-fold: no
Date: Mon, 9 May 88 15:20 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Oh mumble, you're probably right. So setf of find-class will work, but
setf of find-method won't. What about setf of find-generic-function, leave
that out too?
What is find-generic-function? I didn't see any message to suggest that
there would be such a thing. I guess I must have missed something. I
don't understand why symbol-function isn't enough? If function
specifiers do get accepted into Common Lisp (editorial comment almost
elided), there will be some appropriate extension of symbol-function
which we will just use.
-------
∂09-May-88 1820 Common-Lisp-Object-System-mailer Re: Plan Comments
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 9 May 88 18:20:21 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 401207; Mon 9-May-88 21:20:19 EDT
Date: Mon, 9 May 88 21:20 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: Plan Comments
To: common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: <19880509221155.1.GREGOR@PORTNOY.parc.xerox.com>
Message-ID: <19880510012002.6.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Mon, 9 May 88 15:11 PDT
From: Gregor.pa@Xerox.COM
Date: Mon, 9 May 88 15:20 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Oh mumble, you're probably right. So setf of find-class will work, but
setf of find-method won't. What about setf of find-generic-function, leave
that out too?
What is find-generic-function?
I guess I was hoping in vain that ensure-generic-function would be given
a more consistent name. Just forget it.
∂09-May-88 1822 Common-Lisp-Object-System-mailer Re: Plan Comments
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 9 May 88 18:22:46 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 401212; Mon 9-May-88 21:22:46 EDT
Date: Mon, 9 May 88 21:22 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: Plan Comments
To: common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: <19880509221155.1.GREGOR@PORTNOY.parc.xerox.com>
Supersedes: <19880510012002.6.MOON@EUPHRATES.SCRC.Symbolics.COM>
Comments: First think, then press End. I inverted the recommended order.
Message-ID: <19880510012239.7.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Mon, 9 May 88 15:11 PDT
From: Gregor.pa@Xerox.COM
Date: Mon, 9 May 88 15:20 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Oh mumble, you're probably right. So setf of find-class will work, but
setf of find-method won't. What about setf of find-generic-function, leave
that out too?
What is find-generic-function?
I guess I was hoping in vain that ensure-generic-function would be given
a more consistent name. Just forget it. But before you forget it, think
about the fact that ensure-generic-function takes an environment argument
but symbol-function doesn't; thus you can't check whether a generic function
exists in the compile time environment without creating it.
∂09-May-88 2025 Common-Lisp-Object-System-mailer Plan Comments
Received: from labrea.stanford.edu by SAIL.Stanford.EDU with TCP; 9 May 88 20:23:29 PDT
Received: by labrea.stanford.edu; Mon, 9 May 88 20:23:38 PDT
Received: from bhopal.lucid.com by edsel id AA24837g; Mon, 9 May 88 20:12:30 PDT
Received: by bhopal id AA13938g; Mon, 9 May 88 20:15:25 PDT
Date: Mon, 9 May 88 20:15:25 PDT
From: Jon L White <edsel!jonl@labrea.stanford.edu>
Message-Id: <8805100315.AA13938@bhopal.lucid.com>
To: Gregor.pa@xerox.com
Cc: Moon@stony-brook.scrc.symbolics.com, RPG@sail.stanford.edu,
common-lisp-object-system@sail.stanford.edu
In-Reply-To: Gregor.pa@Xerox.COM's message of Mon, 9 May 88 11:20 PDT <19880509182021.9.GREGOR@PORTNOY.parc.xerox.com>
Subject: Plan Comments
re: I think that trying to make setf of find-method work is a bad idea. We
already have add-method and remove-method, they work, and are clear. I
think we are just going to end up with a kludgey sort of interface to
them if we try to make setf of find-method work.
For what it's worth, I agree 100% with you here. The increase in
functionality is truly minimal, for a kludgy and 23rd-hour interface.
-- JonL --
∂10-May-88 1101 Common-Lisp-Object-System-mailer Re: Plan Comments
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 10 May 88 11:01:10 PDT
Received: from Semillon.ms by ArpaGateway.ms ; 10 MAY 88 11:00:43 PDT
Date: Tue, 10 May 88 10:58 PDT
From: Gregor.pa@Xerox.COM
Subject: Re: Plan Comments
To: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
cc: common-lisp-object-system@SAIL.STANFORD.EDU
Fcc: BD:>Gregor>mail>outgoing-mail-2.text.newest
In-Reply-To: <19880510012239.7.MOON@EUPHRATES.SCRC.Symbolics.COM>
Message-ID: <19880510175855.4.GREGOR@PORTNOY.parc.xerox.com>
Line-fold: no
Date: Mon, 9 May 88 21:22 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
I guess I was hoping in vain that ensure-generic-function would be given
a more consistent name. Just forget it. But before you forget it, think
about the fact that ensure-generic-function takes an environment argument
but symbol-function doesn't; thus you can't check whether a generic function
exists in the compile time environment without creating it.
I suspect that cleanup committee proposals to `fix' symbol-function,
symbol-macro, fboundp etc. are needed before this stuff can work
anyways.
So I guess I am saying we should finesse this using the argument that it
is (partly) outside of our charter.
-------
∂10-May-88 2141 Common-Lisp-Object-System-mailer check-keyword-arguments
To: common-lisp-object-system@SAIL.Stanford.EDU
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>
I was editing chapter 1 to reflect the change of flushing check-initargs
in favor of check-keyword-arguments when the ugliness of
check-keyword-arguments started me thinking about what check-initargs was
for.
It was a generic function, so it was originally thought useful for users
to be able to define methods for it. Now that it is a function, that
usefulness is now not thought important.
What else did it do? The primary usefulness of it was to signal an error
with all relevant information in the right place, presumably so that the
error message could be reasonable. Well, we punted on the full specification
of that in CLOS with check-keyword-arguments because we couldn't think of
an elegant way to pass the right information around. Moon then pointed
out that maybe we should fall back on the condition system to help solve the
problem, which is presumably the problem it is designed to solve.
So, why not take that same way out now? Presumably the slot-filler guy who
stuffs initargs into slots is able to signal an error at a reasonable
point, and that condition could be handled in make-instance etc. The
slot-filler guy should be able check all for the existence of all the
slots he was going to try to fill, so the condition can mention all bad
slots. Similarly, keyword arguments that are not acceptable to an
applicable method will also be signaled, and the method who notices it can
report all the keyword arguments it doesn't like or even all the
keywords the generic function and all applicable methods don't like.
The problem with this is that the user will only see one method's (or one
generic function's) worth of bad news at a time. Seeing all the possible
bad news at the same was a primary feature of check-initargs.
Another alternative is to state that the initargs will be checked at
specified points in an implementation-dependent or unspecified way. This
isn't too bad because some of the mechanism is hidden in the current
check-keyword-arguments formulation due to the presumed use of the
condition system. Maybe chapter 37 could describe the general mechanism
for achieving all the right stuff in the places left unspecified.
If you believe that all of the bad initargs must be determined at the same
time and you insist that the mechanism be exposed in chapters 1 and 2,
maybe it would be better for the second argument to be a list of methods
and provide a mechanism for getting all the applicable methods from a
generic function for some set of required arguments. In this way the
ugliness of check-keyword-arguments would be traded off against providing
something else useful to the user.
check-keyword-arguments keyword-argument-plist
methods
&optional extra-allowed-keywords
-rpg-
∂11-May-88 1003 Common-Lisp-Object-System-mailer check-keyword-arguments
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 11 May 88 10:02:54 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 402441; Wed 11-May-88 13:02:23 EDT
Date: Wed, 11 May 88 13:02 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: check-keyword-arguments
To: Dick Gabriel <RPG@SAIL.STANFORD.EDU>
cc: common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: The message of 11 May 88 00:41 EDT from Dick Gabriel <RPG@SAIL.Stanford.EDU>
Message-ID: <19880511170203.3.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: 10 May 88 2141 PDT
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>
....
So, why not take that same way out now? Presumably the slot-filler guy who
stuffs initargs into slots is able to signal an error at a reasonable
point, and that condition could be handled in make-instance etc. The
slot-filler guy should be able check all for the existence of all the
slots he was going to try to fill, so the condition can mention all bad
slots. Similarly, keyword arguments that are not acceptable to an
applicable method will also be signaled, and the method who notices it can
report all the keyword arguments it doesn't like or even all the
keywords the generic function and all applicable methods don't like.
This can't work. A sink for initialization arguments can look at an
initialization argument and say "this isn't one of mine", but it cannot
say "none of the possible sinks for initialization arguments claims this."
The sinks for initialization arguments for make-instance are slot-filling
plus three generic functions' applicable methods' &key parameters.
Something has to consider all four of them together.
Another alternative is to state that the initargs will be checked at
specified points in an implementation-dependent or unspecified way.
In other words, don't include a procedural definition of make-instance
and don't include check-keyword-arguments as a facility that users can
call for their own purposes. I was probably the first to suggest not
including a procedural definition, way back when, so I won't argue
against it, however I don't think you have a strong argument for it yet.
....
If you believe that all of the bad initargs must be determined at the same
time and you insist that the mechanism be exposed in chapters 1 and 2,
maybe it would be better for the second argument to be a list of methods
and provide a mechanism for getting all the applicable methods from a
generic function for some set of required arguments. In this way the
ugliness of check-keyword-arguments would be traded off against providing
something else useful to the user.
I don't see how this makes check-keyword-arguments less ugly. It just
rearranges its interface slightly. Moving compute-applicable-methods
from chapter 3 to chapter 2 would be okay with me if you think it
belongs there. Alternatively, we could decide that the standard-class
method for make-instance belongs in the part of chapter 3 that we don't
agree on yet and remove it from chapter 1. Or we could package the call
to check-keyword-arguments back up inside check-initargs, where it was
until recently, which requires us to introduce three additional versions
of check-initargs to be called by the standard-class methods for the
three other generic functions that can be called with initialization
arguments. To me that would be uglier.
∂11-May-88 2047 Common-Lisp-Object-System-mailer :documentation
To: common-lisp-object-system@SAIL.Stanford.EDU
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>
I have 2 questions about the :documentation slot option and a comment.
In the formulation proposed, there is no indication whether the
:documentation slot option is inherited like :initform or acts like
:reader. I presume since it doesn't specify a characteristic of the slot
it acts like :reader. Yes?
And, if so, should the presence of :documentation in a slot where nothing
like :reader appears signal an error or simply be ignored?
The comment is that :documentation is a cruddy name for this option.
If someone simply reads the syntax description for DEFCLASS there is
no doubt he will believe it is part of some hairy documentation for the
entire class or for the slot.
This example (provided with the synposis I got) is misleading:
(defclass foo ()
((x :reader foo-x
:reader bar-x
:writer (setf foo-x)
:documentation "the x slot stores the x position")))
Do you intend for the documentation of a method to only mention what the
slot is? Or would you expect to see:
(defclass foo ()
((x :reader foo-x
:reader bar-x
:writer (setf foo-x)
:documentation "reader/writer for the x position")))
This points out another problem, which is that someone might want to have
different documentation strings for readers and writers. So why not
:accessor-documentation, :reader-documentation, and :writer-documentation?
I wouldn't mind dumping this one. Do we imagine the Cleanup committee will
never touch CLOS?
-rpg-
∂11-May-88 2114 Common-Lisp-Object-System-mailer Check-keyword-arguments
To: common-lisp-object-system@SAIL.Stanford.EDU
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>
Moon writes:
``This can't work.''
Right.
Moon writes:
``In other words, don't include a procedural definition of make-instance
and don't include check-keyword-arguments as a facility that users can
call for their own purposes. I was probably the first to suggest not
including a procedural definition, way back when, so I won't argue
against it, however I don't think you have a strong argument for it yet.''
I consider arguments of the form ``this formulation is profoundly ugly''
to be strong. I find arguments of the form ``we need a feature
to do some task and here is a kludge that happens to work'' weak.
Moon writes:
``I don't see how this makes check-keyword-arguments less ugly.''
When you have to invent a funny representation to package up arguments
that isn't a simple list (or a property list at the worst), you are
talking ``ugly.''
The second argument in the revised version would be a list of methods,
which is something easy to understand.
We could describe the second argument as an alist of generic functions and
required arguments. This would be the only possible means to approach
retaining check-keyword-arguments as it is.
To show why the current formulation is uglier than some others, consider
this proposal:
Check-keyword-arguments takes a single argument, which is a list of the
form
(keyword-plist (...(generic-function . required args) ...) . optional-keywords)
All I've done is rearrange the interface slightly; therefore its ugliness is
unchanged. The serious point is that the funny representation of the
second argument is something that someone who is reading the definition
of a non-standard make-instance is going to have to scratch his head to
remember.
I prefer the list of methods as the second argument to check-keyword-arguments
to all other solutions. After that, the plethora of function names solution, and
finally the ditch-it solution.
-rpg-
∂11-May-88 2119 Common-Lisp-Object-System-mailer Comments on MOP
Received: from uunet.UU.NET by SAIL.Stanford.EDU with TCP; 11 May 88 21:19:11 PDT
Received: from mcvax.UUCP by uunet.UU.NET (5.54/1.14) with UUCP
id AA16529; Thu, 12 May 88 00:19:07 EDT
Received: by mcvax.cwi.nl; Thu, 12 May 88 03:50:57 +0200 (MET)
Received: by cernvax.uucp (1.2/Ultrix2.0-B)
id AA21382; Wed, 11 May 88 19:13:55 +0200
Received: from mads.delphi.uucp by delphi.uucp (3.2/SMI-3.2)
id AA10755; Wed, 11 May 88 16:46:30 +0200
Received: by mads.delphi.uucp (3.2/SMI-3.0DEV3)
id AA00346; Wed, 11 May 88 16:46:23 +0200
Date: Wed, 11 May 88 16:46:23 +0200
From: mcvax!delphi!chicca@uunet.UU.NET (M.R. Boscotrecase)
Message-Id: <8805111446.AA00346@mads.delphi.uucp>
To: common-lisp-object-system@sail.stanford.edu
Subject: Comments on MOP
Cc: mads!gattardi@uunet.UU.NET, mads!mrboscotrecase@uunet.UU.NET,
mads!smazzini@uunet.UU.NET, mads!tflagella@uunet.UU.NET
Hello! As probably you know we are developing an implementation of
CLOS based on the ObjVlisp model in KCL. We have two questions about
MOP. Is there a person so kind to answer?
We don't agree with your proposal for the implementation of defclass.
You specify that defclass expands to a call to the generic function
add-named-class, passing it a prototype instance of
the class specified by the :metaclass option.
We feel that the introduction of the concept of a prototype instance
is an unnecessary complication. It also invites confusion between the
new class you are creating and the metaclass which is instantiated to
make the prototype instance.
We suggest instead that the concept of metaclass is sufficient to
implement the desired behavior simply by invoking add-named-class with
the metaclass as an argument. Sometimes this approach could require the
introduction of new metaclasses just for the purpose of defining an
add-named-class method, but we don't think this is a significant
overhead. For example we had to introduce the classes
standard-metaclass and structure-metaclass just to provide the
add-named-class method used by their instances standard-class
and structure-class.
The other question concerns the optimization of slot access. In chap.3
the generic function optimize-instance-access is described. Is it
invoked by the compiler in order to optimize instance accessing forms?
Is it correct that when optimize-instance-access is called to
optimize a slot-value form, converting it to a call of
standard-instance-access, slot-missing and slot-unbound are not
also invoked? It is not defined what is an access key. Looking at the
definition of slot-value-using-class in page 3-47 of new-mop it looks
like the access key in a call to standard-instance-access is the
slot name. Is it correct? Is the mapping from slot name to index done
by class-access-keys, which is invoked by standard-instance-access?
Thanks in advance,
Chicca Boscotrecase
DELPHI S.p.A.
Viareggio, ITALY
net: mrboscotrecase%delphi.uucp@uunet.UU.NET
∂12-May-88 0838 Common-Lisp-Object-System-mailer Check-keyword-arguments
To: common-lisp-object-system@SAIL.Stanford.EDU
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>
Here is another approach. I believe we need to have a procedural
definition of make-instance (and maybe other initialization-like
functions), and we need for them to be models for users to imitate.
Therefore, the error situation must be handled correctly in make-instance.
Because check-keyword-arguments is pretty ugly already, why not simply
make it do what it needs to do (and maybe some useful but not required
things too)?
So here's the new specification for check-keyword-arguments:
check-keyword-arguments keywords-or-keyword-plistp
keywords-or-keyword-plisp
generic-functions-and-arguments-or-methods
extra-allowed-keywords
&optional errorp-or-function
keywords-or-keyword-plistp:
I don't think we need to restrict this function to a plist of keywords and
values, as in an initarg list. A list of keywords is a useful argument
too. So the first argument tells which to expect as the second argument.
(I don't think this wrinkle is necessary, so we could drop it.)
keywords-or-keyword-plisp:
Either a list of keywords or a plist of keywords and values.
generic-functions-and-arguments-or-methods:
A list of elements, each of which is either a method or a pair. If an
element is a pair, the car is a generic function and the cdr is a set of
required arguments that are used to select a set of applicable methods. If
the cdr of the pair is nil, all methods for that generic function are
used.
extra-allowed-keywords:
This is a list of additional keywords to consider as legal.
errorp-or-function:
This is an optional argument that defaults to nil. If it is nil, then
check-keyword-arguments returns T if all is well or the list of losing
keywords if some fail to be ok. If it is non-nil, an error will be
signaled. When the error is signaled, the message is constructed from the
value of errorp-or-function. If it is a string, it is taken as a format
string to be included in the message. If it is a symbol, it is taken as
the name of the function in which check-keyword-arguments is being called
and is used in the error message. If it is a function (or generic
function), it is the function in which check-keyword-arguments is being
called and is used in the error message.
I also thought of providing a predicate to test keywords, but this
could be handled outside of check-keyword-arguments.
This is pretty gross, but I think we are concentrating all of the ugliness
in one place, which is better than either spreading it around or
presenting an incomplete procedural definition of make-instance.
-rpg-
∂12-May-88 0955 Common-Lisp-Object-System-mailer :documentation
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 12 May 88 09:54:55 PDT
Received: from JUNCO.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 403272; Thu 12-May-88 12:12:39 EDT
Date: Thu, 12 May 88 12:12 EDT
From: Sonya E. Keene <skeene@STONY-BROOK.SCRC.Symbolics.COM>
Subject: :documentation
To: RPG@SAIL.Stanford.EDU
cc: common-lisp-object-system@SAIL.Stanford.EDU
In-Reply-To: The message of 11 May 88 23:47 EDT from Dick Gabriel <RPG@SAIL.Stanford.EDU>
Message-ID: <19880512161228.9.SKEENE@JUNCO.SCRC.Symbolics.COM>
I agree with your comments and would also like to dump it. It looks
like it documents the slot itself, which it doesn't. It's additional
messy syntax for very little gain. People can achieve the same effect
by writing accessor methods by hand.
If we're going to add features to defclass at this late date, they ought
to be worth adding.
∂12-May-88 1002 Common-Lisp-Object-System-mailer Re: :documentation
Received: from Sun.COM by SAIL.Stanford.EDU with TCP; 12 May 88 10:02:39 PDT
Received: from snail.sun.com by Sun.COM (4.0/SMI-4.0)
id AA07020; Thu, 12 May 88 10:01:42 PDT
Received: from suntana.sun.com by snail.sun.com (4.0/SMI-3.2)
id AA25490; Thu, 12 May 88 09:59:43 PDT
Received: from localhost by suntana.sun.com (3.2/SMI-3.2)
id AA25631; Thu, 12 May 88 09:54:01 PDT
Message-Id: <8805121654.AA25631@suntana.sun.com>
To: Sonya E. Keene <skeene@STONY-BROOK.SCRC.Symbolics.COM>
Cc: RPG@SAIL.Stanford.EDU, common-lisp-object-system@SAIL.Stanford.EDU
Subject: Re: :documentation
In-Reply-To: Your message of Thu, 12 May 88 12:12:00 -0400.
<19880512161228.9.SKEENE@JUNCO.SCRC.Symbolics.COM>
Date: Thu, 12 May 88 09:53:59 -0700
From: kempf@Sun.COM
I'd also agree. Let's drop it.
jak
∂12-May-88 1234 Common-Lisp-Object-System-mailer :documentation
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 12 May 88 12:33:57 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 403501; Thu 12-May-88 15:33:48 EDT
Date: Thu, 12 May 88 15:33 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: :documentation
To: common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: The message of 11 May 88 23:47 EDT from Dick Gabriel <RPG@SAIL.Stanford.EDU>,
<19880512161228.9.SKEENE@JUNCO.SCRC.Symbolics.COM>,
<8805121654.AA25631@suntana.sun.com>
Message-ID: <19880512193339.8.MOON@EUPHRATES.SCRC.Symbolics.COM>
Dumping the :documentation slot option is fine with me. However, since
this was suggested by a comment from an X3J13 member, someone has to
write an explanation of why we rejected the suggestion. We can't say
simply that we didn't like it. Perhaps Dick's message detailing why the
meaning of the option is too ambiguous combined with Sonya's message
pointing out that there is another way to do the same thing, combined
with an older message from (I think) Gregor pointing out that the
:documentation slot option creates documentation for methods, but what
people probably really want is to create documentation for generic
functions, would suffice.
∂12-May-88 1315 Common-Lisp-Object-System-mailer Re: :documentation
Received: from ti.com by SAIL.Stanford.EDU with TCP; 12 May 88 13:15:22 PDT
Received: by ti.com id AA01550; Thu, 12 May 88 15:13:53 CDT
Received: from Kelvin by tilde id AA01050; Thu, 12 May 88 15:08:09 CDT
Message-Id: <2788459495-5196983@Kelvin>
Sender: GRAY@Kelvin.csc.ti.com
Date: Thu, 12 May 88 15:04:55 CDT
From: David N Gray <Gray@DSG.csc.ti.com>
To: common-lisp-object-system@SAIL.STANFORD.EDU
Subject: Re: :documentation
In-Reply-To: Msg of 11 May 88 2047 PDT from Dick Gabriel <RPG@SAIL.STANFORD.EDU>
It appears that the discussion of the :DOCUMENTATION slot option has
strayed away from what my original intent was. The idea was that the
person who is writing a DEFCLASS should have a way to specify
documentation that explains what each slot is for, just as he currently
has a way to document the entire object. What is actually done with the
doc string is really a programming environment issue rather than a
language issue. It would be most useful for a data inspector where the
user could ask for a description of any of the slots of a class or
instance being examined, or for a documentation tool that automatically
generates descriptions of Lisp programs. I suggested using it as the
doc string for the reader method since in most cases a description of
the slot would also be a reasonable description for what the reader
method is for, and the reader method does not have any documentation
otherwise. This is like what we currently do with the :DOCUMENTATION
slot option of DEFSTRUCT (which I just today realized is not standard)
-- it becomes the doc string of the accessor function. That is actually
more meaningful for a defstruct accessor since it documents the function
the user is calling, whereas for a CLOS reader it is the generic
function that you would really want to document.
So I would be content to have the standard say that the :DOCUMENTATION
slot option provides a way to document the slot, but that what, if
anything, is actually done with it is implementation dependent.
-- David Gray
∂12-May-88 1415 Common-Lisp-Object-System-mailer Re: Check-keyword-arguments
Received: from ti.com by SAIL.Stanford.EDU with TCP; 12 May 88 14:14:51 PDT
Received: by ti.com id AA01961; Thu, 12 May 88 16:13:26 CDT
Received: from Jenner by tilde id AA02807; Thu, 12 May 88 16:10:49 CDT
Message-Id: <2788463258-5286523@Jenner>
Date: Thu, 12 May 88 16:07:38 CDT
From: Patrick H Dussud <DUSSUD@Jenner.csc.ti.com>
To: Dick Gabriel <RPG@SAIL.STANFORD.EDU>
Cc: common-lisp-object-system@SAIL.STANFORD.EDU
Subject: Re: Check-keyword-arguments
In-Reply-To: Msg of 12 May 88 0838 PDT from Dick Gabriel <RPG@SAIL.STANFORD.EDU>
Date: 12 May 88 0838 PDT
From: Dick Gabriel <RPG@SAIL.STANFORD.EDU>
Subject: Check-keyword-arguments
Here is another approach. I believe we need to have a procedural
definition of make-instance (and maybe other initialization-like
functions), and we need for them to be models for users to imitate.
Therefore, the error situation must be handled correctly in make-instance.
Because check-keyword-arguments is pretty ugly already, why not simply
make it do what it needs to do (and maybe some useful but not required
things too)?
So here's the new specification for check-keyword-arguments:
check-keyword-arguments keywords-or-keyword-plistp
keywords-or-keyword-plisp
generic-functions-and-arguments-or-methods
extra-allowed-keywords
&optional errorp-or-function
keywords-or-keyword-plistp:
I don't think we need to restrict this function to a plist of keywords and
values, as in an initarg list. A list of keywords is a useful argument
too. So the first argument tells which to expect as the second argument.
(I don't think this wrinkle is necessary, so we could drop it.)
keywords-or-keyword-plisp:
Either a list of keywords or a plist of keywords and values.
You could consider the the following instead:
check-keyword-arguments keywords-plist
keywords
generic-functions-and-arguments-or-methods
extra-allowed-keywords
&optional errorp-or-function
Keyword-plist is passed as a key value sequence,
keywords is a list of keywords.
This is more powerful since you are not constrained to one keyword format for one
call.
∂12-May-88 1415 Common-Lisp-Object-System-mailer Re: Check-keyword-arguments
Received: from ti.com by SAIL.Stanford.EDU with TCP; 12 May 88 14:14:57 PDT
Received: by ti.com id AA01965; Thu, 12 May 88 16:13:31 CDT
Received: from Jenner by tilde id AA02819; Thu, 12 May 88 16:11:06 CDT
Message-Id: <2788463283-5288013@Jenner>
Date: Thu, 12 May 88 16:08:03 CDT
From: Patrick H Dussud <DUSSUD@Jenner.csc.ti.com>
To: Dick Gabriel <RPG@SAIL.STANFORD.EDU>
Cc: common-lisp-object-system@SAIL.STANFORD.EDU
Subject: Re: Check-keyword-arguments
In-Reply-To: Msg of 12 May 88 0838 PDT from Dick Gabriel <RPG@SAIL.STANFORD.EDU>
Date: 12 May 88 0838 PDT
From: Dick Gabriel <RPG@SAIL.STANFORD.EDU>
Subject: Check-keyword-arguments
Here is another approach. I believe we need to have a procedural
definition of make-instance (and maybe other initialization-like
functions), and we need for them to be models for users to imitate.
Therefore, the error situation must be handled correctly in make-instance.
Because check-keyword-arguments is pretty ugly already, why not simply
make it do what it needs to do (and maybe some useful but not required
things too)?
So here's the new specification for check-keyword-arguments:
check-keyword-arguments keywords-or-keyword-plistp
keywords-or-keyword-plisp
generic-functions-and-arguments-or-methods
extra-allowed-keywords
&optional errorp-or-function
keywords-or-keyword-plistp:
I don't think we need to restrict this function to a plist of keywords and
values, as in an initarg list. A list of keywords is a useful argument
too. So the first argument tells which to expect as the second argument.
(I don't think this wrinkle is necessary, so we could drop it.)
keywords-or-keyword-plisp:
Either a list of keywords or a plist of keywords and values.
You could consider the the following instead:
check-keyword-arguments keywords-plist
keywords
generic-functions-and-arguments-or-methods
extra-allowed-keywords
&optional errorp-or-function
Keyword-plist is passed as a key value sequence,
keywords is a list of keywords.
This is more powerful since you are not constrained to one keyword format for one
call.
Patrick.
∂12-May-88 1454 Common-Lisp-Object-System-mailer Re: :documentation
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 12 May 88 14:54:43 PDT
Received: from Semillon.ms by ArpaGateway.ms ; 12 MAY 88 14:46:47 PDT
Date: Thu, 12 May 88 14:46 PDT
From: Gregor.pa@Xerox.COM
Subject: Re: :documentation
To: Sonya E. Keene <skeene@STONY-BROOK.SCRC.Symbolics.COM>
cc: RPG@SAIL.Stanford.EDU, common-lisp-object-system@SAIL.Stanford.EDU
Fcc: BD:>Gregor>mail>outgoing-mail-2.text.newest
In-Reply-To: <19880512161228.9.SKEENE@JUNCO.SCRC.Symbolics.COM>
Message-ID: <19880512214643.3.GREGOR@PORTNOY.parc.xerox.com>
Line-fold: no
I agree too. Let's dump it.
-------
∂12-May-88 1605 Common-Lisp-Object-System-mailer Re: :documentation
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 12 May 88 16:05:01 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 403727; Thu 12-May-88 19:04:44 EDT
Date: Thu, 12 May 88 19:04 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: :documentation
To: common-lisp-object-system@SAIL.STANFORD.EDU
cc: David N Gray <Gray@DSG.csc.ti.com>
In-Reply-To: <2788459495-5196983@Kelvin>
Message-ID: <19880512230437.0.MOON@EUPHRATES.SCRC.Symbolics.COM>
That's an interesting piece of input which changes some
things.
I would suggest, then, that the :documentation slot-option should be
put in, and that it should not set the documentation of any function
or method. Instead, it should set the documentation of the slot,
which requires the chapter 2 function documentation to be enhanced to
accept slot-descriptions as well as the other meta-objects it accepts,
and the chapter 3 specification of slot-descriptions to be enhanced to
mention that they have documentation that can be initialized, read,
and written. As with all Common Lisp documentation strings, what use
if any is made of this data is implementation-dependent; CLOS just
provides a place to store it.
∂12-May-88 1650 Common-Lisp-Object-System-mailer Re: :documentation
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 12 May 88 16:50:29 PDT
Received: from Semillon.ms by ArpaGateway.ms ; 12 MAY 88 16:39:35 PDT
Date: Thu, 12 May 88 16:39 PDT
From: Gregor.pa@Xerox.COM
Subject: Re: :documentation
To: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
cc: common-lisp-object-system@SAIL.STANFORD.EDU, David N Gray
<Gray@DSG.csc.ti.com>
Fcc: BD:>Gregor>mail>outgoing-mail-2.text.newest
In-Reply-To: <19880512230437.0.MOON@EUPHRATES.SCRC.Symbolics.COM>
Message-ID: <19880512233933.0.GREGOR@PORTNOY.parc.xerox.com>
Line-fold: no
Date: Thu, 12 May 88 19:04 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
I would suggest, then, that the :documentation slot-option should be
put in, and that it should not set the documentation of any function
or method. Instead, it should set the documentation of the slot,
.
.
This seems fine with me. It requires mentioning that slot description
objects exist in chapter 2, but that shouldn't be a problem. Let's do
this.
-------
∂13-May-88 2103 Common-Lisp-Object-System-mailer Chapter 1
To: common-lisp-object-system@SAIL.Stanford.EDU
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>
Chapter 1 is available from concep.tex[cls,lsp] or concep.dvi[cls,lsp]
on SAIL. Except for what we decide to do with check-keyword-arguments,
pagination, and a new X3J13 number this should be the final version.
I've removed all pagination commands from the tex source, so the
pagination will be bad. (That is, no comments about it, please.)
Sonya and Dave: I also tried to tidy up the description of what happens to
local and shared slots in the section on redefining a class. I think the
previous version required the reader to have too much state in mind while
reading. Please look at this section carefully.
I will be away monday, tuesday, and wednesday, and I think we should aim
for mailing a week from Monday. That means the copy shop must have them
by friday afternoon.
-rpg-
∂15-May-88 1054 Common-Lisp-Object-System-mailer Re: Check-keyword-arguments
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 15 May 88 10:54:34 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 15 MAY 88 10:54:40 PDT
Date: 15 May 88 10:54 PDT
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Re: Check-keyword-arguments
In-reply-to: Patrick H Dussud <DUSSUD@Jenner.csc.ti.com>'s message of Thu, 12
May 88 16:07:38 CDT
To: DUSSUD@Jenner.csc.ti.com
cc: RPG@SAIL.STANFORD.EDU, common-lisp-object-system@SAIL.STANFORD.EDU
Message-ID: <880515-105440-7624@Xerox>
You could consider the the following instead:
check-keyword-arguments keywords-plist
keywords
generic-functions-and-arguments-or-methods
extra-allowed-keywords
&optional errorp-or-function
Keyword-plist is passed as a key value sequence,
keywords is a list of keywords.
I like this. There is one reason that argues against including methods in the
third argument. The user might think that an arbitrary set of methods can be
included. However, for the intended purpose, it only makes sense if all the
methods applicable to a particular set of arguments are included. The value
returned can also be incoherent if there are included methods of the same
generic function which are never applicable together. It is for this reason
that the generic-functions-and-arguments list was suggested in the first place.
danny
∂15-May-88 1356 Common-Lisp-Object-System-mailer check-keyword-arguments
To: common-lisp-object-system@SAIL.Stanford.EDU
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>
Danny writes:
``There is one reason that argues against including methods in the third
argument. The user might think that an arbitrary set of methods can be
included. However, for the intended purpose, it only makes sense if all
the methods applicable to a particular set of arguments are included.''
Check-keyword-arguments is a pretty ugly function, at least in terms of
its interface. One reason to tolerate it is that it can be useful in other
situations. One of the situations might be as part of someone's funny CASE
system in which as methods are defined, all places in the current sources
that invoke the generic function are checked in a cursory way for those
invocations that might fail to pass the keyword arguments test on this
method. One might argue that this is a poor example, but why assume that
our intended use is the only use, especially if we are trying to
generalize check-keyword-arguments to make it palatable.
One of the interesting things about the whole check-initargs affair is
that it is one the few places where a lot of effort is being made to worry
about the behavior of incorrect programs. Remember, Common Lisp itself
tends to say nothing about the behavior of incorrect programs (there are
generally in error) and even the most that CLOS typically says is that
errors are signaled or generic functions are invoked in spurious
situations.
Here we are specifying the function that checks for a particular error.
To me, a program that contains both a :type slot option and a setf that
violates it is incorrect. We have gone to no effort to make it any easier
than programming to check these erroneous programs.
I have no worries that someone who is writing his own version of
make-instance could look in chapter 3 or 4 to find out how to do error
checking. Therefore, only a check-keyword-arguments that is more generally
useful justifies going beyond specifying a procedural definition of
make-instance that is reasonable only for correct invocations of it.
-rpg-